两个指令创建新的继承的和隔离的作用域-元素得到哪个

two directives creating new inherited and isolated scope - which one does the element get

本文关键字:作用域 隔离 元素 继承 两个 指令 创建      更新时间:2023-09-26

例如,我有自己的指令来创建隔离范围:

angular.module("main", []).directive("makeIsolateScope", function () {
    return {
        scope: {
            node: node
        }
    }
});

然后我将它与ng-repeat一起使用,后者创建了新的继承范围:

<li ng-repeat="node in nodes" make-isolate-scope="node">{{node.name}}</li>

元素li的作用域是什么?

事实证明,元素将有两个作用域:

  • ng重复指令创建的子作用域

    angular.element(el).scope();

  • 隔离makeIsolateScope指令创建的作用域:

    angular.element(el).isolateScope();

订单如下:

1) 调用ng-repeat的编译函数,并且不将优先级低于2000ng-repeat's优先级)的所有其他指令作为编译节点的一部分进行编译。这意味着现在makeIsolateDirective没有被编译。

2) 由于ng-repeat被定义为transclude:element,整个节点被编译为transclusion编译过程的一部分,现在makeIsolateDirective被编译并执行其编译功能。

3) 执行ng-repeat的链接函数,接收$transcludeFn函数。此$transcludeFn函数执行n次,接收针对父节点的子作用域(由transclusion机制创建)编译的克隆dom:

$transclude(function ngRepeatTransclude(clonedDom, scope) {
    // here clonedDom is the clone of the original <li> node

4) makeIsolateBindings的链接函数是在由该指令创建的独立作用域中执行的。作用域的父级是rootScope。

不创建隔离作用域的其他指令的链接函数使用子作用域执行,该子作用域在ng-repeat的链接函数中与$transcludeFn一起使用。

创建隔离作用域并从父级请求$$isolateBindings的指令是根据ng-repeat的transclusion机制创建的子作用域进行评估的。以下是源代码摘录:

forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
...
case '=':
...
lastValue = isolateBindingContext[scopeName] = parentGet(scope); // the scope here is the child's scope created by transclusion

这篇文章对理解$transcludeFn的工作原理非常有用。

每个指令都有一个priority编号,它是$compile的指导。默认优先级编号为0,ng-repeat为1000。因此,如果你把1001作为指令的优先级,它将提前编译,否则ng repeat将提前编译。

为了避免这些麻烦,只需将指令移动到li中即可。。