角度指令范围问题

时间:2013-09-27 17:02:16

标签: angularjs angularjs-directive angularjs-scope

我现在有角色的经验,但我仍然无法弄明白。我通过另一个directive1转换了一个指令2。 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/

2 个答案:

答案 0 :(得分: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放在指令上。

我希望这会有所帮助。

答案 1 :(得分:1)

.directive('directive2', function() {
    return {
        restrict: 'A',
        controller: 'Controller',
        link: function(scope, elem, attrs) {
            console.log('from directive2', scope);
        }
    }
});

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

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