【问题标题】:Why are the children of directives not able to read scope of its directive?为什么指令的子级无法读取其指令的范围?
【发布时间】:2025-12-20 06:00:17
【问题描述】:

我对 angularjs 指令中的范围有疑问。请看下面的代码:

HTML:

<div ng-controller="MyCtrl">
<!-- 1. works: -->
<pre>{{controllerItems}}</pre>


<my-list attr-items="controllerItems">

  <!-- 3. works not: -->
  <pre>{{directiveItems}}</pre>

  <!-- 4. works: -->
  <pre>{{controllerItems}}</pre>
</my-list>
</div>

JS:

angular.module('myapp', [])

.controller('MyCtrl', function($scope) {
    $scope.controllerItems = [
        'A', 'B', 'C', 'D'    
    ];
})

.directive('myList', function () {
    return {
      restrict: 'E',
      transclude : true,
      template : '<!-- 2. works: --><pre>{{directiveItems}}</pre><div ng-transclude></div>',
      scope : {
        directiveItems : '=attrItems'
      },
      link: function (scope, element, attrs, ctrl) {
        //console.log(scope);
      }
    }
}); 

我试图做的是为指令及其所有子项创建一个自己的范围。我使用 scope : { } 为指令创建了一个新范围,并且预期该指令的所有子级都可以使用它。但我得到的是,3. 不知道 directiveItems 并且在 4. 中,父范围仍然存在。

我的问题:如何使用指令创建单独的范围,该指令也适用于所有子元素,如 {{ }} 或其他默认和自定义元素?

您也可以在这里找到代码:http://plnkr.co/edit/kKtGdNt8Jq09zabwVoJo?p=preview

感谢您的帮助!

【问题讨论】:

    标签: javascript angularjs angularjs-scope angular-directive


    【解决方案1】:

    模板中使用的 ng-transclude 指令将转入的内容绑定到一个新范围,该范围在原型上继承父范围(通过 scope.$new())。因此,这个新范围可以看到 controllerItems,并且隔离范围变量directiveItems 不可用。

    如果您想将被嵌入的内容绑定到隔离范围,请使用传递给链接函数的 transcludeFn 并将其传递给隔离范围。请注意,当您执行此操作时,controllerItems 将不再可用:

    .directive('myList', function () {
        return {
          restrict: 'E',
          transclude : true,
          template : '<pre>{{directiveItems}}</pre>',
          scope : {
            directiveItems : '=attrItems'
          },
          link: function (scope, element, attrs, ctrl, transcludeFn) {
             //Bind the transcluded content to the isolated scope
             transcludeFn(scope, function (clone) {
                element.after(clone);
             }
          }
        }
    }); 
    

    http://jsfiddle.net/vjxn7qyc/1/

    谨慎使用它,因为隔离作用域应该这样做,将自身与外部代码隔离。当您嵌入声称知道隔离范围的内容时,您就是在违反规则:)。

    【讨论】:

    • 非常感谢 - 正是我想要的!