在我的应用程序中,我有一个所谓的“递归”指令,用于实现包含自身实例的元素层次结构(如树),这种方法要求我实现我在Stack Overflow上找到的自定义编译器函数,因为Angular的否则编译器就会进入无限循环。
这是具有编译器功能的工厂:
SBApp.factory('RecursionHelper', ['$compile', function($compile){
return {
compile: function(element, link){
if(angular.isFunction(link)){
link = { post: link };
}
var contents = element.contents().remove();
var compiledContents;
return {
pre: (link && link.pre) ? link.pre : null,
post: function(scope, element){
if(!compiledContents){
compiledContents = $compile(contents);
}
compiledContents(scope, function(clone){
element.append(clone);
});
if(link && link.post){
link.post.apply(null, arguments);
}
}
};
}
};
}]);
该代码成功打破了无限循环。
现在,使用这段代码的指令运行得很完美,但是我已经到了需要强制重新编译指令的地步,因为指令的某些父作用域中的数据发生了变化因此需要观察属性值并更新指令,并且它的子节点相应地通过我所谓的树结构“传播”变化。
我在SO:$compile(element.contents())(scope);
的某处找到了这段代码,但这并没有削减它,因为我需要使用自定义编译功能来打破无限循环。
这是我的指令:
SBApp.directive('collection', function(RecursionHelper, TemplateFactory, $compile){
return{
restrict: 'E',
scope:{
collection: '=',
editable: '=?',
adminEdit: '=?'
},
templateUrl:'templates/collection.html',
compile: function(element){
var l = function(scope, element, attrs){
scope.$watch('adminEdit', function() {
//I need help with this part
});
//rest of the
//scope functions
//and directive code
}; //end of link function
return RecursionHelper.compile(element, l);
}
};
});
问题如下:我找不到在RecursionHelper.compile()
函数内成功调用scope.$watch
函数的方法,并在adminEdit
属性更改时强制重新编译元素。我已经尝试了我能想到的所有可能的组合,但似乎没有任何效果。
唯一可行的方法是在指令之前添加第三个布尔变量和ng-if,然后将布尔变量切换两次以强制删除并强制添加元素,但这不是我正在寻找的干净解决方案。
使用自定义编译功能时如何实现强制编译?
修改我已经通过使用范围解决了这个问题。$ watch更新了数据并发现实际上track by $index
通过创建其他范围导致了所有问题我不需要它,它以某种方式搞砸了我试图创建的指令的层次结构。尽管如此,这个问题仍然存在,因为我无法找到一种方法来动态重新编译一个带有自定义编译功能的指令,如前面所述。