2013-12-16 72 views
31

当我尝试在同一元素上嵌套两个指令时,出现以下错误。 嵌套的“E”指令 - 多个指令要求新的/隔离的范围, 我想嵌套两个“E”隔离的作用域指令,如this fiddle。 (要真正重现该问题,您需要取消对<LW>指令)如何在AngularJS的相同元素上嵌套两个指令?

我不断收到这个错误,我不知道/知道如何解决:

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

是不是这个应该工作? 谢谢!

回答

59

删除更换:在该指令真正的名字 'LW' ..

这也应该解决。

更新小提琴:updated fiddle

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

分析:

是什么原因造成的问题?

用lw指令替换为true会发生什么是lw有隔离作用域,现在作为替换= true,被替换的元素本身具有隔离范围试图在那里被替换,所以你在不知不觉中做了什么,为同一元素列表提供两个范围。在angular.js 1.2.1版

代码级的观察:

线5728:功能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)); 
     } 
    } 

以上是这是否检查功能,并且如果万一有分配两个作用域到相同元件的尝试它甩这个错误。 所以这就是它被设计成的样子,而不是一个错误。

为什么要替换:真正的删除解决了这个问题?

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

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

为什么包装在一个div也将工作(这是你认为是解决方法解决方案)?

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

所以这就是它是如何设计的工作,绝对不是一个错误。

+1

圣牛,真棒回答,谢谢! –

+1

为了保持'replace:true'功能,我选择使用div来包装模板。它解决了这个问题,由此产生的html与'replace:true'是“更干净”。感谢你的回答! –

+0

感谢这个简短的解释!你为我节省了很多时间! –

5

我设法解决它通过替换包装指令中的模板代码。 这是update fiddle。 这是改变了。

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

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

有 - https://github.com/angular/angular.js/issues/5428

+0

这是最简单的方法来解决他的问题,这不是一个错误 – gr3g

+0

这也解决了我的问题,谢谢。 – surfitscrollit

11

只是为了感兴趣,我有同样的错误。事实证明,因为我做了旧的“剪切和粘贴”来创建一个新的指令,他们有相同的名称开始。我忘了改变它产生这个错误。

因此,对于任何与我一样糟糕的人,那么这里有一个可能的解决方案来检查。

+1

谢谢我在这个问题和其他问题中尝试了所有其他解决方案,但是当看到您的问题时,我记得我将一个指令从一个文件夹复制到另一个文件夹,但忘记删除旧定义,因此每个指令都定义了两次,尽管是两个不同的模块。 –

+0

BAH!...“Ol'cut'N paste” - 如果可以的话,我会加倍努力:-P ...谢谢! – Cody

0

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

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

4

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

+0

即使您声明特定于某个模块的指令,它似乎也是如此,它会在全局范围内注册。我不知道这是否是设计。看起来像是一个bug – fernando

3

我用复仇者例子,更新到1.4角后,我开始这一点。事实证明,它有一个控制器和一个指令战斗范围在同一行

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

所以移动控制器到一个单独的范围,以解决它。

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

在我来说,我有过NG重复的元素上的引导,UI手风琴组指令:

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

而且通过这样做解决了它:

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