实际上,我在一个指令的编译函数中使用了两个模板。我在指令的编译阶段一次性编译它们(通过$compile)。在指令的链接阶段,我观察了一个作用域变量,并将一个或另一个已编译的模板应用于该作用域。
testApp.directive('testField', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: true,
compile: function(tElement, tAttrs) {
var viewFn = $compile("<div>View: <span ng-repeat='x in [1,2,3]'>{{x}}</span></div>");
var editFn = $compile("<div>Edit: <span ng-repeat='x in [4,5,6]'>{{x}}</span></div>");
return function (scope, element, attrs) {
var innerScope = null;
scope.$watch("mode", function (mode) {
if (innerScope) innerScope.$destroy();
innerScope = scope.$new();
if (mode == 'VIEW') {
element.empty().append(viewFn(innerScope));
} else {
element.empty().append(editFn(innerScope));
}
});
};
}
};
}]);它工作得很好,除非模板包含一个不是根元素的Ng-repeat,在这种情况下,它的行为很奇怪:
要进行复制,请转到http://plnkr.co/edit/RCqlNWTVdXVoMQCkFcQn?p=preview并多次从编辑切换到视图。
您将注意到ng-repeat的迭代次数随着时间的推移而增长。第一次,它显示123和456,就像它应该显示的那样
第一次在查看和编辑之间来回切换后,将显示123123和456456
而且每次你在视图和编辑之间来回切换时,它都会不断地添加一个迭代。
发布于 2015-08-12 15:01:42
我可能在发帖后不久就找到了解决方案。
问题很明显存在于ng-repeat需要克隆模板的事实中。
在偶然发现angular源代码中的注释之后,我们可以向compile返回的函数传递第二个参数。
第二个参数是通过模板的克隆(以及链接到的作用域)调用的函数。
因此,不是
if (mode == 'VIEW') {
element.empty().append(viewFn(innerScope));
} else {
element.empty().append(editFn(innerScope));
}我能做到
function setElts(elts) {
element.empty().append(elts);
}
if (mode == 'VIEW') {
viewFn(innerScope, setElts);
} else {
editFn(innerScope, setElts);
}发布于 2015-08-12 15:09:59
也许你可以像this那样做。
首先,在视图中直接注入新的dom。之后,捕获它并应用$compile。
像这样;
var viewFn = "<div>View: <span ng-repeat='x in [1,2,3]'>{{x}}</span></div>";
...
element.html(viewFn);
...
$compile(tElement.contents())(innerScope);https://stackoverflow.com/questions/31957525
复制相似问题