在我的理解中,$compile 应该能够支持嵌套指令编译/链接,但是我们遇到了编译/链接不完整的问题——只有最外层的指令被渲染到 DOM 中,并且只有在以下两种情况下才会重现该问题真的:
- 内部指令模板通过 templateUrl 加载(例如异步方式)
- 编译是在 Angular 上下文之外触发的。
我写了一个 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>'
};
});
有趣的是,我可以通过在 compile() 调用(第 27 行)之后的某处调用 scope.$apply() 或将 $timeout(function(){}) 调用添加到内部指令之一的链接函数中(第 41 行)来解决这个问题)。这是缺陷还是设计使然?