我正在寻找任何方式访问“父”范围内的指令。范围、排除、要求、从上面传入变量(或范围本身)等的任何组合。我完全愿意竭尽全力,但我想避免一些完全俗气或无法维护的东西。例如,我知道我现在可以通过从preLink参数中获取$范围并迭代它的$sibling范围来找到概念上的“父”。

我真正想要的是能够在父作用域中监视一个表达式。如果我能做到这一点,那么我就能完成我在这里想做的事情: AngularJS -如何渲染变量的部分?

需要注意的是,该指令必须在相同的父作用域内可重用。因此,默认行为(范围:false)不适合我。我需要每个指令的实例都有一个单独的作用域,然后我需要$watch一个存在于父作用域中的变量。

一个代码示例值1000字,因此:

app.directive('watchingMyParentScope', function() {
    return {
        require: /* ? */,
        scope: /* ? */,
        transclude: /* ? */,
        controller: /* ? */,
        compile: function(el,attr,trans) {
            // Can I get the $parent from the transclusion function somehow?
            return {
                pre: function($s, $e, $a, parentControl) {
                    // Can I get the $parent from the parent controller?
                    // By setting this.$scope = $scope from within that controller?

                    // Can I get the $parent from the current $scope?

                    // Can I pass the $parent scope in as an attribute and define
                    // it as part of this directive's scope definition?

                    // What don't I understand about how directives work and
                    // how their scope is related to their parent?
                },
                post: function($s, $e, $a, parentControl) {
                    // Has my situation improved by the time the postLink is called?
                }
            }
        }
    };
});

当前回答

 scope: false
 transclude: false

你会有相同的作用域(父元素)

$scope.$watch(...

有很多方法来访问父作用域取决于这两个选项作用域&穿透。

其他回答

 scope: false
 transclude: false

你会有相同的作用域(父元素)

$scope.$watch(...

有很多方法来访问父作用域取决于这两个选项作用域&穿透。

如果你使用ES6的Classes和ControllerAs语法,你需要做一些稍微不同的事情。

请参阅下面的代码片段,并注意vm是在父HTML中使用的父控制器的ControllerAs值

myApp.directive('name', function() {
  return {
    // no scope definition
    link : function(scope, element, attrs, ngModel) {

        scope.vm.func(...)

尝试了一切办法,我终于想出了一个解决办法。

只需在模板中放置以下内容:

{{currentDirective。attr = parentDirective.attr;"}}

它只是将您想要访问的父作用域属性/变量写入当前作用域。

还要注意;,以确保模板中没有输出。(Angular计算每条语句,但只输出最后一条)。

这有点俗气,但经过几个小时的试验和错误,它可以工作。

参见AngularJS中作用域原型/原型继承的细微差别是什么?

总结一下:一个指令访问它的父($parent)作用域的方式取决于该指令创建的作用域的类型:

default (scope: false) - the directive does not create a new scope, so there is no inheritance here. The directive's scope is the same scope as the parent/container. In the link function, use the first parameter (typically scope). scope: true - the directive creates a new child scope that prototypically inherits from the parent scope. Properties that are defined on the parent scope are available to the directive scope (because of prototypal inheritance). Just beware of writing to a primitive scope property -- that will create a new property on the directive scope (that hides/shadows the parent scope property of the same name). scope: { ... } - the directive creates a new isolate/isolated scope. It does not prototypically inherit the parent scope. You can still access the parent scope using $parent, but this is not normally recommended. Instead, you should specify which parent scope properties (and/or function) the directive needs via additional attributes on the same element where the directive is used, using the =, @, and & notation. transclude: true - the directive creates a new "transcluded" child scope, which prototypically inherits from the parent scope. If the directive also creates an isolate scope, the transcluded and the isolate scopes are siblings. The $parent property of each scope references the same parent scope.Angular v1.3 update: If the directive also creates an isolate scope, the transcluded scope is now a child of the isolate scope. The transcluded and isolate scopes are no longer siblings. The $parent property of the transcluded scope now references the isolate scope.

上面的链接有这四种类型的例子和图片。

你不能访问指令的compile函数中的作用域(如这里提到的:https://github.com/angular/angular.js/wiki/Dev-Guide:-Understanding-Directives)。你可以在link函数中访问该指令的作用域。

看:

为1。和2。上图:通常你通过一个属性指定指令需要哪个父属性,然后$watch它:

<div my-dir attr1="prop1"></div>
scope.$watch(attrs.attr1, function() { ... });

如果你正在观察一个对象属性,你需要使用$parse:

<div my-dir attr2="obj.prop2"></div>
var model = $parse(attrs.attr2);
scope.$watch(model, function() { ... });

为3。上面(隔离作用域),注意使用@或=符号给指令属性命名:

<div my-dir attr3="{{prop3}}" attr4="obj.prop4"></div>
scope: {
  localName3: '@attr3',
  attr4:      '='  // here, using the same name as the attribute
},
link: function(scope, element, attrs) {
   scope.$watch('localName3', function() { ... });
   scope.$watch('attr4',      function() { ... });

这里有一个我曾经用过的技巧:创建一个“dummy”指令来保存父范围,并将其放置在所需指令之外的某个地方。喜欢的东西:

module.directive('myDirectiveContainer', function () {
    return {
        controller: function ($scope) {
            this.scope = $scope;
        }
    };
});

module.directive('myDirective', function () {
    return {
        require: '^myDirectiveContainer',
        link: function (scope, element, attrs, containerController) {
            // use containerController.scope here...
        }
    };
});

然后

<div my-directive-container="">
    <div my-directive="">
    </div>
</div>

也许不是最优雅的解决方案,但它完成了任务。