根据我的理解,$ compile应该能够支持嵌套的指令编译/链接,但是我们遇到了一个问题,即编译/链接是不完整的 - 只有最外层的指令被渲染到DOM中,并且只有在以下条件属实:
我写了一个jsfiddler来演示它,下面列出了部分代码,完整案例http://jsfiddle.net/pattern/7KjWP/
myApp.directive('plTest', function($compile){
return {
restrict :'A',
scope: {},
replace: true,
template: '<div>plTest rendered </div>',
link: function (scope, element){
$('#button1').on('click', function(){
var ele;
ele = $compile('<div pl-shared />')(scope);
console.log('plTest compile got : '+ ele[0].outerHTML);
// scope.$apply();
element.append(ele);
});
}
};
});
myApp.directive('plShared', function($compile, $timeout){
return {
restrict: 'A',
scope: {},
replace: true,
link: function (scope, element){
// comment out below line to make render success
//$timeout(function(){});
var el = $compile('<div pl-item></div>')(scope);
console.log('plShared compile got:' + el[0].outerHTML);
element.append(el);
}
};
});
myApp.directive('plItem', function($timeout){
return {
restrict: 'A',
scope:{},
template:'<div>plItem rendered <div pl-avatar/></div>',
link: function(scope){
}
};
});
myApp.directive('plAvatar', function(){
return {
restrict: 'A',
scope: {}
, templateUrl: 'avatar.html'
// ,template: 'content of avatar.html <div pl-image></div>'
};
});
有趣的是,我可以通过调用scope来解决这个问题。$ apply()在compile()调用之后的某个地方(第27行) 或者将$ timeout(function(){})调用添加到内部指令(第41行)之一的链接函数中。这是缺陷还是设计?
答案 0 :(得分:3)
$(foo).on(bar, handler)
是一个jQuery事件,这意味着AngularJS不知道它的具体细节,并且在它处理所有绑定之后不会(不能)运行apply-digest cycle。
scope.$apply
是为此而做的,正如你正确地说的那样,修复它。经验法则是:如果您使用其他库在AngularJS应用程序中实现UI功能(特别是:在apply-digest循环之外),您必须自己调用scope.$apply
。
HTH!
答案 1 :(得分:0)
在element.append(el)之后,尝试再次编译,因为刚刚修改了DOM。
您可以尝试使用$compile(element)(scope);
或$compile(element.contents())(scope);
等内容。
如前所述,我还会更改事件处理程序,如下所示:
$('#button1').on('click', function(){
scope.$apply( function(){
//blablalba
});
});
另外,如果您想要缩小代码,请提供一些建议,我将使用以下语法声明编译依赖项:
.directive('directiveName',['$service1',''$service2,...,'$compile', function($service1, $service2,...,$compile){
//blablabla
}]}