更好的解决方案(新):
读完后角度文档 http://docs.angularjs.org/api/ng/service/%24compile我遇到过这个:
您可以将模板指定为表示模板的字符串或指定为
函数接受两个参数 tElement 和 tAttrs(在
下面的编译函数 api)并返回一个表示的字符串值
模板。
所以我的新指令看起来像这样:(我相信这是处理此类事情的适当“角度”方式)
app.directive('page', function() {
return {
restrict: 'E',
replace: true,
template: function(tElement, tAttrs) {
var isClickable = angular.isDefined(tAttrs.isClickable) && eval(tAttrs.isClickable) === true ? true : false;
var clickAttr = isClickable ? 'ng-click="onHandleClick()"' : '';
return '<div ' + clickAttr + ' ng-transclude></div>';
},
transclude: true,
link: function(scope, element, attrs) {
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
请注意新的模板函数。现在,我在编译该函数之前操作该函数内的模板。
替代解决方案(旧):
Added replace: true
摆脱重新编译指令时的无限循环问题。然后在链接函数中,我只是在添加新属性后重新编译元素。但有一点需要注意,因为我有一个ng-transclude
指令在我的元素上,我需要删除它,这样它就不会尝试在第二次编译时包含任何内容,因为没有任何内容可以包含。
这就是我的指令现在的样子:
app.directive('page', function() {
return {
restrict: 'E',
replace: true,
template: '<div ng-transclude></div>',
transclude: true,
link: function(scope, element, attrs) {
var isClickable = angular.isDefined(attrs.isClickable) && scope.$eval(attrs.isClickable) === true ? true : false;
if (isClickable) {
attrs.$set('ngClick', 'onHandleClick()');
element.removeAttr('ng-transclude');
$compile(element)(scope);
}
scope.onHandleClick = function() {
console.log('onHandleClick');
};
}
};
});
不过,我认为第二次重新编译模板并不理想,所以我觉得在第一次编译模板之前仍然有办法做到这一点。