gpt4 book ai didi

angularjs - 在模板中非法使用 ngTransinclude 指令

转载 作者:行者123 更新时间:2023-12-02 19:38:59 33 4
gpt4 key购买 nike

我有两个指令

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', function ($compile) {
return {
restrict: "E",
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:orphan] 在模板中非法使用 ngTransclude 指令!未找到需要嵌入的父指令。元素:<div class="ng-scope" ng-transclude="">

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

我在 http://docs.angularjs.org/error/ngTransclude:orphan 上看到一些解释。但我不知道为什么会出现此错误以及如何解决它。

编辑我创建了一个jsfiddle页。预先感谢您。

编辑

In my real app panel1 does something like this:

<panel1>
<input type="text>
<input type="text>
<!--other elements or directive-->
</panel1>

结果=>

    <div>
<div class="x"><input type="text></div>
<div class="x"><input type="text></div>
<!--other elements or directive wrapped in div -->
</div>

最佳答案

原因是当 DOM 加载完成后,Angular 将遍历 DOM 并将所有指令转换为模板调用编译和链接函数。

这意味着当您调用$compile(clone.children()[0])(scope)时,clone.children()[0]这是你的<panel>在这种情况下,已经被 Angular 转换clone.children()已经变成:

<div ng-transclude="">fsafsafasdf</div>

(面板元素已删除并替换)。

这与你用 ng-transclude 编译普通 div 是一样的。当你用ng-transclude编译一个普通的div时, Angular 抛出异常,如文档中所述:

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"><div ng-transclude=""><div ng-transclude="" class="ng-scope"><div ng-transclude="" class="ng-scope">fsafsafasdf</div></div></div></panel>

这也是有问题的,因为 ng-transclude是重复的

DEMO

为了避免与 Angular 编译过程发生冲突,我建议设置 <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', function ($compile) {
return {
restrict: "E",
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。只需使用开箱即用的 ng-transclude .

app.directive('panel1', function ($compile) {
return {
restrict: "E",
replace:true,
transclude: 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', function ($compile) {
return {
restrict: "E",
replace:true,
transclude: true,
template:"<div ng-transclude></div>",
link: function (scope, elem, 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

关于angularjs - 在模板中非法使用 ngTransinclude 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20718127/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com