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

前端之家收集整理的这篇文章主要介绍了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看到一些解释。但是不知道为什么我在这里有这个错误,如何解决它。

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

编辑

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>在这种情况下已经被角度变换了。
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:

<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

原文链接:https://www.f2er.com/angularjs/144607.html

猜你在找的Angularjs相关文章