【问题标题】:angular directive scoping issue角度指令范围问题
【发布时间】:2013-10-04 01:53:34
【问题描述】:

我现在有一些角度方面的经验,但我仍然无法弄清楚那个。我有一个指令 2 通过另一个指令 1 嵌入。 Directive1 与控制器位于同一元素上,并且它们共享相同的范围。我希望directive2 从控制器的范围继承,但不是父/子,而是兄弟姐妹。我在这里错过了什么?

代码如下:

angular.module('myModule', [])
    .controller('Controller', ['$scope', function($scope) {
        console.log('from controller', $scope);
    }])
    .directive('directive1', function(){
        return {
            restrict: 'A',
            replace: true,
            transclude: true,
            template:  '<div style="width:150px;"> <p>directive1</p>'
            +'<div style="width:100px;" ng-transclude></div> </div>',
            link: function($scope, elem, attrs){
                console.log('from directive1', $scope);
            }
        }
    })
    .directive('directive2',  function(){
        return {
            restrict: 'A',
            link: function($scope, elem, attrs) {
                console.log('from directive2', $scope);
            }
        }
    });

相关的html:

<div x-directive1 ng-controller="Controller">
    <div x-directive2> <p>directive2</p> </div>
</div>

还有一个指向 jsFiddle 的链接:http://jsfiddle.net/RFontana/Lm7gA/1/

【问题讨论】:

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:
.directive('directive2', function() {
    return {
        restrict: 'A',
        controller: 'Controller',
        link: function(scope, elem, attrs) {
            console.log('from directive2', scope);
        }
    }
});

我不会使用 $scope 作为这些链接函数的命名参数,而是使用 'scope'。 这给了directive2那个Controller,但我不认为这真的是你想要的。 你能不能把控制器移动到一个封闭的 div 上?那么directive2 实际上会继承控制器范围。

<div ng-controller="Controller">
    <div x-directive1>
        <div x-directive2> <p>directive2</p> </div>
    </div>
</div>

【讨论】:

  • 对范围变量使用 $scope 是一个坏主意,但这不是导致此问题的原因。这里描述的问题是一个范围层次问题,具体由在也承载 ng-controller 指令的第一个指令中使用 ng-transclude 引起。 My answer提供了解决方案的jsFiddle和详细解释的链接。
【解决方案2】:

问题在于将ng-controller 直接放在执行嵌入的父指令上。 Transclusion directives create a new scope。创建一个包装元素并在其上放置ng-controller 指令。

像这样:

<section ng-controller="Controller">
    <div x-directive1>
        <div x-directive2> <p>directive2</p> </div>
    </div>
</section>

我有 forked your fiddle 并在其中放置了修复程序。

为什么内部指令显示为兄弟(来自官方 AngularJS 指令文档):

transclude - 编译元素的内容并使其可用 到指令。通常与 ngTransclude 一起使用。的优势 嵌入是链接函数接收到一个嵌入 预先绑定到正确范围的函数。 在典型设置中 小部件创建一个隔离范围,但嵌入不是 子,但是隔离范围的兄弟。 这使得它成为可能 具有私有状态的小部件,以及要绑定到的嵌入 父(预隔离)范围。

在您的情况下,您没有在父指令上声明隔离范围,而是在父指令上声明控制器。嵌入导致子指令成为其父级和控制器的同级作用域,因为控制器位于父级上。

我的建议,避免将ng-controller 放在指令上。

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2013-10-07
    • 1970-01-01
    相关资源
    最近更新 更多