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>
这意味着当你调用$ compile(clone.children()[0])(scope)时,clone.children()[0]是< panel>在这种情况下已经被角度变换了。
clone.children()已经变成:
< divng-transclude =“”> fsafsafasdf< / div>
(面板元件已被移除并更换)。
你正在编辑一个正常的div与ng-transclude是一样的。当您使用ng-transclude编译正常的div时,角度抛出异常,如文档中所述:
This error often occurs when you have forgotten to set transclude:
true in some directive definition,and then used ngTransclude in the
directive’s template.
即使您设置replace:false来保留您的< panel>,有时您会看到这样的转换元素:
< panel class =“ng-scope”>< divng-transclude =“”>< divng-transclude =“”class =“ng-scope”>< divng-transclude =类= “NG-范围” > fsafsafasdf< / DIV>< / DIV>< / DIV>< /面板>
这也是有问题的,因为ng-transclude是重复的
为了避免与角度编译过程冲突,我建议设置< 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>",} });
正如你所看到的,这个代码很干净,因为我们不需要手动处理元素。
更新了一个解决方案来动态添加元素,而不使用模板或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); } } });
如果你想把它放在html页面上,确保不要再编译它:
如果您需要为每个孩子添加一个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 } } });