angularjs – 在模板中非法使用ngTransclude指令

前端之家收集整理的这篇文章主要介绍了angularjs – 在模板中非法使用ngTransclude指令前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有两个指令
  1. app.directive('panel1',function ($compile) {
  2. return {
  3. restrict: "E",transclude: 'element',compile: function (element,attr,linker) {
  4. return function (scope,element,attr) {
  5. var parent = element.parent();
  6. linker(scope,function (clone) {
  7. parent.prepend($compile( clone.children()[0])(scope));//cause error.
  8. // parent.prepend(clone);// This line remove the error but i want to access the children in my real app.
  9. });
  10. };
  11. }
  12. }
  13. });
  14.  
  15. app.directive('panel',replace: true,transclude: true,template: "<div ng-transclude ></div>",link: function (scope,elem,attrs) {
  16. }
  17. }
  18. });

这是我的观点:

  1. <panel1>
  2. <panel>
  3. <input type="text" ng-model="firstName" />
  4. </panel>
  5. </panel1>

错误:[ngTransclude:孤儿]在模板中非法使用ngTransclude指令!没有发现需要发现的父母指令。元素:< div class =“ng-scope”ng-transclude =“”>

我知道panel1不是一个实用的指令。但在我的真实应用中,我也遇到这个问题。

我在http://docs.angularjs.org/error/ngTransclude:orphan看到一些解释。但是不知道为什么我在这里有这个错误,如何解决它。

编辑
我创建了一个jsfiddle页面。先谢谢你。

编辑

  1. I my real app panel1 does something like this:
  2.  
  3. <panel1>
  4. <input type="text>
  5. <input type="text>
  6. <!--other elements or directive-->
  7. </panel1>

result =>

  1. <div>
  2. <div class="x"><input type="text></div>
  3. <div class="x"><input type="text></div>
  4. <!--other elements or directive wrapped in div -->
  5. </div>
原因是当DOM完成加载时,角度将遍历DOM,并在调用编译和链接功能之前将所有指令转换为其模板。

这意味着当你调用$ 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.

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:

  1. <div data-ng-app="app">
  2. <panel1>
  3.  
  4. </panel1>
  5. </div>

你的JS:

  1. app.directive('panel1',function ($compile) {
  2. return {
  3. restrict: "E",template:"<panel><input type='text' ng-model='firstName'>{{firstName}}</panel>",}
  4. });

正如你所看到的,这个代码很干净,因为我们不需要手动处理元素。

DEMO

更新了一个解决方案来动态添加元素,而不使用模板或templateUrl:

  1. app.directive('panel1',template:"<div></div>",link : function(scope,element){
  2. var html = "<panel><input type='text' ng-model='firstName'>{{firstName}}</panel>";
  3. element.append(html);
  4. $compile(element.contents())(scope);
  5. }
  6. }
  7. });

DEMO

如果你想把它放在html页面上,确保不要再编译它:

DEMO

如果您需要为每个孩子添加一个div。只需使用开箱即用的转义。

  1. app.directive('panel1',replace:true,template:"<div><div ng-transclude></div></div>" //you could adjust your template to add more nesting divs or remove
  2. }
  3. });

DEMO(您可能需要根据需要调整模板,删除div或添加更多div)

基于OP的更新问题的解决方案:

  1. app.directive('panel1',template:"<div ng-transclude></div>",attrs) {
  2. elem.children().wrap("<div>"); //Don't need to use compile here.
  3. //Just wrap the children in a div,you could adjust this logic to add class to div depending on your children
  4. }
  5. }
  6. });

DEMO

猜你在找的Angularjs相关文章