angularjs – 在模板中非法使用ngTransclude指令
我有两个指令
app.directive('panel1',function ($compile) { return { restrict: "E",transclude: 'element',compile: function (element,attr,linker) { return function (scope,element,attr) { var parent = element.parent(); linker(scope,function (clone) { parent.prepend($compile( clone.children()[0])(scope));//cause error. // parent.prepend(clone);// This line remove the error but i want to access the children in my real app. }); }; } } }); app.directive('panel',replace: true,transclude: true,template: "<div ng-transclude ></div>",link: function (scope,elem,attrs) { } } }); 这是我的观点: <panel1> <panel> <input type="text" ng-model="firstName" /> </panel> </panel1> 错误:[ngTransclude:孤儿]在模板中非法使用ngTransclude指令!没有发现需要发现的父母指令。元素:< div class =“ng-scope”ng-transclude =“”> 我知道panel1不是一个实用的指令。但在我的真实应用中,我也遇到这个问题。 我在http://docs.angularjs.org/error/ngTransclude:orphan看到一些解释。但是不知道为什么我在这里有这个错误,如何解决它。 编辑 编辑 I my real app panel1 does something like this: <panel1> <input type="text> <input type="text> <!--other elements or directive--> </panel1> result => <div> <div class="x"><input type="text></div> <div class="x"><input type="text></div> <!--other elements or directive wrapped in div --> </div>
原因是当DOM完成加载时,角度将遍历DOM,并在调用编译和链接功能之前将所有指令转换为其模板。
这意味着当你调用$ compile(clone.children()[0])(scope)时,clone.children()[0]是< panel>在这种情况下已经被角度变换了。 < divng-transclude =“”> fsafsafasdf< / div> (面板元件已被移除并更换)。 你正在编辑一个正常的div与ng-transclude是一样的。当您使用ng-transclude编译正常的div时,角度抛出异常,如文档中所述:
DEMO(检查控制台看输出) 即使您设置replace:false来保留您的< panel>,有时您会看到这样的转换元素: < panel class =“ng-scope”>< divng-transclude =“”>< divng-transclude =“”class =“ng-scope”>< divng-transclude =类= “NG-范围” > fsafsafasdf< / DIV>< / DIV>< / DIV>< /面板> 这也是有问题的,因为ng-transclude是重复的 DEMO 为了避免与角度编译过程冲突,我建议设置< panel1>的内部html作为模板或templateUrl属性 您的HTML: <div data-ng-app="app"> <panel1> </panel1> </div> 你的JS: app.directive('panel1',function ($compile) { return { restrict: "E",template:"<panel><input type='text' ng-model='firstName'>{{firstName}}</panel>",} }); 正如你所看到的,这个代码很干净,因为我们不需要手动处理元素。 DEMO 更新了一个解决方案来动态添加元素,而不使用模板或templateUrl: app.directive('panel1',template:"<div></div>",link : function(scope,element){ var html = "<panel><input type='text' ng-model='firstName'>{{firstName}}</panel>"; element.append(html); $compile(element.contents())(scope); } } }); DEMO 如果你想把它放在html页面上,确保不要再编译它: DEMO 如果您需要为每个孩子添加一个div。只需使用开箱即用的转义。 app.directive('panel1',replace:true,template:"<div><div ng-transclude></div></div>" //you could adjust your template to add more nesting divs or remove } }); DEMO(您可能需要根据需要调整模板,删除div或添加更多div) 基于OP的更新问题的解决方案: app.directive('panel1',template:"<div ng-transclude></div>",attrs) { elem.children().wrap("<div>"); //Don't need to use compile here. //Just wrap the children in a div,you could adjust this logic to add class to div depending on your children } } }); DEMO (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |