当多个指令共享相同的元素时,混淆AngularJS范围

时间:2015-06-11 00:51:20

标签: angularjs angularjs-directive angularjs-scope

所有

我是AngularJS指令范围的新手,我想知道当多个隔离范围指令分配给同一个元素时,AngularJS如何处理范围。

例如:

app.controller("main", function($scope){
    $scope.data = [
        {
            id:"id_1"
        },
        {
            id:"id_2"
        },
        {
            id:"id_3"
        },
        {
            id:"id_4"
        }
    ];
});

app.directive("isodir", function(){
    return {
        restrict:"AE",
        scope: {},
        controller: function($scope){$scope.d = {id:"isodir_id"} },
        link: function(scope, EL, attrs){}
    }
});

HTML部分是:

<isodir ng-repeat="d in data track by $index">{{d.id}}</isodir>

<isodir>{{d.id}}</isodir>

主要有两个问题让我很困惑:

  

[1]对于html部分[1]:有ng-repeat的那个,任何人都可以给我   关于如何 AngularJS决定使用范围的一些解释,因为   ng-repeat和isodir都是孤立的范围(根据结果,   但事实证明,ng-repeat范围得到应用,我想知道原因   不是isodir应用);有时如果我使用两个指令同时隔离   范围,AngularJS将报告错误。 ng-repeat没有报告   错误。

     

[2]对于html部分[2]:没有ng-repeat的那个,让我们说我   只是毫无疑问地接受关于[1]部分的事实,那就意味着   ng-repeat范围内的d 被渲染到{{d.id}},但在[2]中,   我在isodir控制器中定义$ scope.d,但为什么这个d可以   用作{{d.id}}

的值

由于

1 个答案:

答案 0 :(得分:1)

1)这将与$ compile命令有关,其中首先执行具有较高优先级的指令。 ngRepeat的优先级为1000,高于自定义指令0。 但是对于你的情况,你使用的ng-bind-html {{d.id}}将不适用于自定义指令,因为你有一个隔离范围所以它希望{{d.id}}将绑定在里面指令模板,而不是在它之外。即使用template或templateUrl。

检查第一个plunkr,它是您的指令的固定版本

app.directive('isodir', function(){
return {
    restrict:"AE",
    priority: 0,
    template: "{{d.id}}",
    scope: {},
    controller: function($scope){$scope.d = {id:"isodir_id"} }
}
});

http://plnkr.co/edit/3noKzbJGMav7MBozW4i0?p=preview

正如你所看到的结果是isodir,因为它是最新的编译因此覆盖了ng-repeat d scope。

将它与第二个plunkr进行比较,哪个自定义指令的优先级高于ngRepeat

app.directive('isodir', function(){
return {
    restrict:"AE",
    priority: 100000,
    template: "{{d.id}}",
    scope: {},
    controller: function($scope){$scope.d = {id:"isodir_id"} }
}
});

http://plnkr.co/edit/1RhF0LpvfBOaVPZju6Fr?p=preview

正如您所见,ng-repeat覆盖{{d.id}}以使用ngRepeat范围对象。

2)如上所述,这是由于孤立的范围。如果要在没有模板/模板URL的自定义指令中使用{{d.id}},则必须删除隔离范围。