Javascript 使用自定义编译函数重新编译AngularJS指令
在我的应用程序中,我有一个所谓的“递归”指令用于实现元素层次结构(如树),它包含自身的实例,这种方法要求我实现一个自定义编译器函数,我在堆栈溢出中发现了该函数,因为Angular的编译器否则只会进入一个无限循环 这是具有编译器功能的工厂:Javascript 使用自定义编译函数重新编译AngularJS指令,javascript,angularjs,Javascript,Angularjs,在我的应用程序中,我有一个所谓的“递归”指令用于实现元素层次结构(如树),它包含自身的实例,这种方法要求我实现一个自定义编译器函数,我在堆栈溢出中发现了该函数,因为Angular的编译器否则只会进入一个无限循环 这是具有编译器功能的工厂: SBApp.factory('RecursionHelper', ['$compile', function($compile){ return { compile: function(element, link){
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);
}
}
};
}
};
}]);
该代码成功地打破了无限循环
现在,使用此代码的指令工作正常,但我需要强制重新编译该指令及其子项,因为该指令的某些父作用域中的数据发生了变化,因此我需要观察atribute值,并相应地更新该指令及其子项以“传播”通过我所拥有的所谓的树结构的改变
我在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()
函数的方法。$watch
函数,如果adminEdit
属性更改,则强制重新编译元素。我已经尝试了我能想到的所有可能的组合,但似乎没有任何效果
唯一有效的方法是在指令之前添加第三个布尔变量和ng if,然后切换布尔变量两次以强制移除并强制添加元素,但这不是我要寻找的干净解决方案
使用自定义编译函数时如何实现强制编译
Edit:我已经通过使用scope.$watch更新数据解决了这个问题,并发现实际上是track by$index
通过创建我不需要的其他作用域造成了所有的麻烦,它以某种方式破坏了我试图创建的指令的层次结构。尽管如此,问题仍然悬而未决,因为我找不到一种方法来使用上述自定义编译函数动态地重新编译指令。您真的需要编译函数吗?指令内容是否包含一些必须编译的HTML代码?否则,只需使用双向数据绑定即可解决问题。更改将自动更新到所有子指令。看起来你手动编译了指令的内容,不需要这样做。adminEdit
是一个布尔变量,它确实在children指令中更新,但当我切换该布尔值时,问题就出现了-children指令中依赖于它的范围变量没有被正确地重新计算,因为它们不知道链接函数中的代码执行时发生的更改仅在编译指令时执行一次。但是,你给了我一个主意。我将adminEdit
变量作为一个属性“传播”,因此我将尝试添加一个范围。$watch
函数在终端节点指令中,并执行更新指令的操作,看看这是否有帮助。这就是您的操作方式;)只需构建一个观察者来观察您所需的属性并执行这些操作,您在link函数中所做的操作(将其放在函数中以避免重复代码)不,这在这种情况下没有帮助。显然,我在ng repeat中遇到了一些非常深刻和复杂的问题,即呈现集合树和/或需要重新编译指令的指令。任何帮助都将不胜感激。看来问题已经解决了。我使用ng repeat
和track by$index
遍历集合。我一按$index删除曲目
问题就消失了。这可能造成了给我带来麻烦的额外范围。如果一切正常,我会汇报,并更新问题。不过,重新编译问题仍然存在。您真的需要编译函数吗?指令内容是否包含一些必须编译的HTML代码?否则,只需使用双向数据绑定即可解决问题。更改将自动更新到所有子指令。看起来你手动编译了指令的内容,不需要这样做。adminEdit
是一个布尔变量,它确实在children指令中更新,但当我切换该布尔值时,问题就出现了-children指令中依赖于它的范围变量没有被正确地重新计算,因为它们不知道链接函数中的代码执行时发生的更改仅在编译指令时执行一次。但是,你给了我一个主意。我将adminEdit
变量作为一个属性“传播”,因此我将尝试添加一个范围。$watch
函数在终端节点指令中,并执行更新指令的操作,看看这是否有帮助。这就是您的操作方式;)只需构建一个观察者来观察您所需的属性并执行这些操作,您在link函数中所做的操作(将其放在函数中以避免重复代码)不,这在这种情况下没有帮助。显然,我在ng repeat中遇到了一些非常深刻和复杂的问题,即呈现集合树和/或需要重新编译指令的指令。任何帮助都将不胜感激。看来问题已经解决了。我使用ng repeat
和track by$index
遍历集合。我一按$index删除曲目
问题就消失了。这可能造成了给我带来麻烦的额外范围。如果一切正常,我会汇报,并更新问题。不过,重新编译的问题仍然存在。