如何在 AngularJS 中的同一个元素上嵌套两个指令? [英] How to nest two directives on the same element in AngularJS?

查看:25
本文介绍了如何在 AngularJS 中的同一个元素上嵌套两个指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在同一个元素上嵌套两个指令时,出现以下错误.嵌套的E"指令 - 多个指令 [...] 要求新的/隔离的范围,我想嵌套两个E"独立作用域指令,例如 this fiddle.(要真正重现该问题,您需要取消注释 <lw> 指令)

我不断收到我不理解/不知道如何解决的错误:

错误:[$compile:multidir] 多个指令 [lw, listie] 请求新的/隔离的作用域:<listie items="items items">

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

解决方案

remove replace: true on thedirective by name 'lw' ..

那也应该解决.

更新小提琴:更新小提琴

app.directive('lw', function(){返回 {限制:'E',范围: {项目:="},模板:'<listie items="items"></listie>',控制器:功能($范围){}}});

分析:

导致问题的原因是什么?

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

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

第 5728 行:函数 applyDirectivesToNode 是在指令上执行编译的函数,在第 5772 行,他们会检查我们是否尝试分配重复的作用域,或者换句话说,具有两个作用域的相同元素.

function assertNoDuplicate(what, previousDirective, directive, element) {如果(上一个指令){throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] 请求 {2} on: {3}',previousDirective.name,directive.name,what,startingTag(element));}}

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

为什么replace:true删除可以解决问题?

通过删除 replace:true 发生的事情是代替新指令 listie 被替换而不是 lw ,它被附加到其中,因此它是一个嵌套在其他范围内的隔离范围,这是绝对正确和允许的.嵌套的隔离范围就像

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

</lw>

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

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

这就是它的工作原理,绝对不是错误.

When I try to nest two directives on the same element I get the following error. Nested "E" directives - Multiple directives [...] asking for new/isolated scope, I want to nest two "E" isolated scoped directives, like in this fiddle. (To actually reproduce the problem, you need to uncomment the <lw> directive)

I keep getting this error that I don't understand/know how to fix:

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

Wasn't this supposed to work? Thanks!

解决方案

remove replace: true on the directive by name 'lw' ..

That should also solve .

updated fiddle : updated fiddle

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

Analysis :

what caused the problem ?

with replace=true for the lw directive what happens is lw has isolate scope, now as replace=true , the replaced element which itself has isolate scope was tried to be replaced there, so what you unknowingly did is you tried to give two scopes for the same element listie.

code level observation in angular.js version 1.2.1:

line 5728 : function applyDirectivesToNode is the function that executes compile on directive and here in line 5772 they do this checking if we are trying to assign duplicate scope or in other words same element with two scopes .

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));
      }
    }

above is the function which does that check and if in case there is an attempt to assign two scopes to same element it flings that error . So this is how it is designed to be and not a bug .

why replace:true removal solves the problem ?

by removing replace:true what happened is instead of new directive listie replaced instead of lw , it got appended into it , so it is one isolated scope nested into other, which is absolutely correct and allowed . the nested isolate scope is like

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

why wrapping in a div will also work (this is your solution which you considered to be workaround) ?

The point to be noted is that the div is not an element with a separate isolate scope .It is just an element. here on replace you are attaching the isolate scope of lw to be attached to a div . (NOTE : The div by itself does not have an isolate scope ), so there is no 2 isolate scopes attached to same element div . so there is no duplication so the assert step passed and it started working .

So this is how it is designed to work and definitely its not a bug .

这篇关于如何在 AngularJS 中的同一个元素上嵌套两个指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆