自定义指令和内置指令之间的优先级

Priority between custom and built-in directve

我正在阅读 ng-book-r27

有些地方不是很明白

关于第 'Directives Explained' 章的 'Scope Option'。

第一个困惑:

If multiple directives on an element provide an isolate scope, only one new scope is applied. Root elements within the template of a directive always get a new scope; thus, for those objects, scope is set to true by default.

我认为这意味着其他指令将使用隔离范围作为它们的范围。 是吗?

第二个困惑:

example of inherited scope

ng-init 比自定义指令具有更高的优先级。 为什么ng-init的表达式会使用自定义指令的作用域

我从官方文档中找到了关于 ng-init 的推荐:

This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.

OK,二次混淆的奇怪行为我可以忽略

我没看过ng-book这本书,但据我所知,你第一个混淆的说法不符合AngularJS documentation关于指令中的继承和隔离范围。

上面的语句根本不可能,有多个指令,每个指令都有自己的 isolated 范围会产生 $compile:multidir error. Here is a DEMO.

.directive('elem1', function($rootScope) {

  return {
    restrict: 'A',
    scope: {}
  };

})

.directive('elem2', function() {
  return {
    restrict: 'A',
    scope: {}
  }
});

扫描AngularJS文档后,没有支持声明的支持声明:

If multiple directives on an element provide an isolate scope, only one new scope is applied.

我看到的最接近上面语句的语句是创建指令时的scope: true选项定义:

true: A new child scope that prototypically inherits from its parent will be created for the directive's element. If multiple directives on the same element request a new scope, only one new scope is created. The new scope rule does not apply for the root of the template since the root of the template always gets a new scope.

上面的陈述表明,当带有 scope: true 选项的多个指令(不是一个独立的范围)驻留在一个元素中时,它将创建一个范围,而其他所有内容都是一个共享范围。 DEMO

.directive('elem1', function($rootScope) {

  return {
    restrict: 'A',
    scope: true,
    link: function(scope) {
      console.log(scope.hello);
    }
  };

})

.directive('elem2', function() {
  return {
    restrict: 'A',
    scope: true,
    link: function(scope) {
      scope.hello = 'world';
      console.log(scope.hello);
    }
  }
});

你会注意到两个指令都记录 'world',这显然支持上面的说法。


如果您在 $compile scope AngularJS documentation 中阅读更多内容,您会看到:

In general it's possible to apply more than one directive to one element, but there might be limitations depending on the type of scope required by the directives. The following points will help explain these limitations. For simplicity only two directives are taken into account, but it is also applicable for several directives:

no scope + no scope => Two directives which don't require their own scope will use their parent's scope

child scope + no scope => Both directives will share one single child scope

child scope + child scope => Both directives will share one single child scope

isolated scope + no scope => The isolated directive will use it's own created isolated scope. The other directive will use its parent's scope

isolated scope + child scope => Won't work! Only one scope can be related to one element. Therefore these directives cannot be applied to the same element.

isolated scope + isolated scope => Won't work! Only one scope can be related to one element. Therefore these directives cannot be applied to the same element.

也许您在识别原型继承作用域和独立作用域之间的区别时遇到了问题。您可能想阅读 $rootScope.Scope $new() 方法,isolate 参数定义。

第一个问题:

I think that mean other directives will use the isolate scope as theirs. is that right?

答案绝对是否定的,在引用具有隔离范围的多个指令时,它会产生 $copile:multidir 错误。

关于你的第二个问题:

ng-init has higher priority than custom directive. Why the expression of ng-init will use the scope of custom directive?

至于没有隔离作用域的指令或没有从其父作用域原型继承的指令,您可以直接将这些指令关联为具有 scope 属性 定义和错误范围值:

falsy: No scope will be created for the directive. The directive will use its parent's scope

如果一个指令被绑定到一个有它自己作用域的元素,那么它只使用该元素的作用域,否则它会寻找作用域链中的所有作用域实例,直到它到达 $rootScope