如何在AngularJS中的同一元素上嵌套两个指令?

时间:2013-12-16 11:26:38

标签: angularjs angularjs-directive

当我尝试在同一个元素上嵌套两个指令时,我得到以下错误。 嵌套“E”指令 - 多个指令[...]要求新的/隔离范围, 我想嵌套两个“E”孤立的范围指令,如this fiddle。 (要实际重现问题,您需要取消注释< lw>指令)

我一直收到这个我不明白/知道如何解决的错误:

Error: [$compile:multidir] Multiple directives [lw, listie] asking for new/isolated scope on: <listie items="items items">

这不应该起作用吗? 谢谢!

7 个答案:

答案 0 :(得分:61)

删除指令中的替换:true ,名称为“lw”..

那也应该解决。

更新小提琴:updated fiddle

app.directive('lw', function(){
    return {
        restrict: 'E',
        scope: {
            items: "="
        },
        template: '<listie items="items"></listie>',
        controller: function($scope) {
        }
    }
});

分析:

导致问题的原因是什么?

对于lw指令使用replace = true会发生什么是lw具有隔离范围,现在作为replace = true,替换的元素本身具有隔离范围,试图在那里替换,所以你在不知不觉中做的是你试图给同一元素列表的两个范围。

angular.js版本1.2.1中的代码级别观察:

第5728行:function applyDirectivesToNode是执行编译指令的函数,在第5772行,如果我们尝试分配重复的范围,或者换句话说,使用两个范围分配相同的元素,它们会执行此操作。

function assertNoDuplicate(what, previousDirective, directive, element) {
      if (previousDirective) {
        throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
            previousDirective.name, directive.name, what, startingTag(element));
      }
    }

以上是执行该检查的函数,如果尝试将两个范围分配给同一个元素,则会抛出该错误。 所以这就是设计的原因而不是错误。

为什么要替换:true删除解决问题?

通过删除replace:true发生了什么而不是新的指令listie替换而不是lw,它被附加到其中,所以它是一个嵌套到其他的隔离范围,这是绝对正确和允许的。 嵌套的隔离范围就像

<lw items="items" class="ng-isolate-scope">
   <div items="items" class="ng-isolate-scope">
        ..........
   </div>
</lw>

为什么包装div也会有用(这是您认为是解决方法的解决方案)?

需要注意的是,div不是具有单独隔离范围的元素。它只是一个元素。 在这里替换你附加lw的隔离范围将附加到div。 (注意:div本身没有隔离范围),因此没有附加2个隔离范围 相同的元素div。 所以没有重复,所以断言步骤通过,它开始工作。

所以这就是设计工作的方式,绝对不是错误。

答案 1 :(得分:11)

为了利益,我有同样的错误。结果是因为我做了旧的&#34;剪切和粘贴&#34;创建一个新的指令,它们的名称相同。我忘了改变它产生了这个错误。

所以对于那些和我一样糟糕的人来说,这里有一个可能的解决方案。

答案 2 :(得分:5)

我设法通过替换wrapper指令中的模板代码来修复它。 这是update fiddle。 这就是改变了。

template: '<div><listie items="items"></listie></div>',
//template: '<listie items="items"></listie>', bug?

这解决了我的问题,但对我来说这看起来像个错误。我想我会在Github上创建一个问题。

那里 - https://github.com/angular/angular.js/issues/5428

答案 3 :(得分:4)

我的问题是因为我将指令JS文件包括两次

答案 4 :(得分:3)

我正在使用复仇者的例子,在更新到角度1.4之后,我开始得到这个。事实证明,它有一个控制器和指令在同一行上争取范围

   <div my-directive ng-controller="myController as vm"></div>

因此将控制器移动到一个单独的范围来修复它。

<div my-directive >
<div ng-controller="myController as vm">
</div>
</div> 

答案 5 :(得分:0)

已接受的回复here为我解决了问题。

基本上从指令中删除隔离的范围,而是通过指令的link函数(在attributes参数中)传递scope属性。

答案 6 :(得分:0)

在我的情况下,我对一个有ng-repeat的元素有一个bootstrap-ui accordion-group指令:

<accordion-group is-open="status.open" ng-repeat="receipt in receipts">

通过这样做解决了这个问题:

<div ng-repeat="receipt in receipts">
    <accordion-group is-open="status.open">