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

时间:2015-12-16 06:18:24

标签: angularjs scope directive

我正在阅读 ng-book-r27

有一些我无法理解的东西。

关于'范围选项'章节'指令解释'。

首先是混乱:

  

如果元素上的多个指令仅提供隔离范围   应用了一个新范围。模板中的根元素   指令总是得到一个新的范围;因此,对于那些对象,范围是   默认设置为true。

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

第二个困惑:

example of inherited scope

ng-init的优先级高于custom指令。 为什么ng-init的表达式将使用自定义dirctive的范围。

我从官方文档中找到关于ng-init的建议:

  

可以滥用此指令来添加不必要的逻辑量   你的模板。 ngInit只有少数适​​当的用途,例如   至于别名ngRepeat的特殊属性,如演示中所示   下面;并通过服务器端脚本注入数据。除了这些   在少数情况下,您应该使用控制器而不是ngInit来初始化   范围内的值。

好吧,我可以忽略第二次混乱的奇怪行为。

1 个答案:

答案 0 :(得分:4)

我没有读过这本书ng-book,但就我所知,你的第一次混淆的陈述与继承和隔离范围的 AngularJS documentation 不一致在指令中。

上述声明根本不可能,如果有多个指令,每个指令都有自己的isolated范围,则会产生 $compile:multidir 错误。这是一个 DEMO

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

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

})

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

扫描AngularJS文档后,没有支持声明来验证语句:

  

如果元素上的多个指令仅提供隔离范围   一个新的范围被应用。

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

  

true:从其父级原型继承的新子范围   将为指令的元素创建。如果有多个指令   同一个元素请求一个新范围,只创建一个新范围。   因此,新范围规则不适用于模板的根   模板的根始终会获得新的范围。

上面的陈述表明,当具有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 中阅读了更多内容,您会看到:

  

通常,可以将多个指令应用于一个指令   元素,但可能存在限制,具体取决于范围的类型   指令要求。以下几点将有助于解释   这些限制。为简单起见,仅采用了两个指令   帐户,但它也适用于几个指令:

     

没有范围+没有范围 =>两个不需要自己范围的指令将使用其父级的范围

     

子范围+无范围 =>这两个指令将共享一个子范围

     

子范围+子范围 =>这两个指令将共享一个子范围

     

隔离范围+无范围 => Isolated指令将使用它自己创建的隔离范围。另一个指令将使用其父级的范围

     

隔离范围+子范围 => 无效!只有一个范围可以与一个元素相关。因此,这些指令不能应用于同一元素。

     

隔离范围+隔离范围 =>不会工作!只有一个范围可以与一个元素相关。因此,这些指令不能应用于同一元素。

也许您在确定原型嵌入范围和隔离范围之间的区别时遇到了问题。您可能需要阅读 $rootScope.Scope $new() 方法,isolate参数定义。

第一个问题:

  

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

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

关于你的第二个问题:

  

ng-init的优先级高于custom指令。为什么表达   ng-init将使用自定义指令的范围?

对于没有独立范围或指令但未从其父范围原型继承的指令,您可以直接将这些指令关联为具有scope属性定义和假范围值:

  

falsy:不会为该指令创建范围。该指令将   使用其父母的范围

如果指令绑定到具有其自身范围的元素,则它只使用该元素的范围,否则它将查找范围链中的所有范围实例,直到它到达$rootScope