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