我试图在触发任何其他指令之前修改Angular模板,特别是插值。我是通过指令定义中的compile
选项来完成的。
这是我的测试代码:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
<script>
angular.module('soQuestion', [])
.directive('example', function () {
return {
compile: function (tElement, tAttrs) {
if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
tElement.attr('foo', 'prefix-' + tAttrs.foo);
console.log(tElement.attr('foo'));
}
}
};
})
.controller('controller', function($scope) {
$scope.value = 'something';
});
</script>
</head>
<body ng-app="soQuestion">
<div ng-controller="controller">
<div example foo="keyword_{{value}}"></div>
</div>
</body>
</html>
但是,即使<div foo="keyword_something"></div>
功能被正确触发,我得到的最终结果是<div foo="prefix-keyword_something"></div>
而不是compile
。这是怎么回事?
答案 0 :(得分:1)
这是一个指令优先问题,而且我还是不完全明白。但是不要因为{{}}
本身就是一个指令。它会与你的某些顺序一起应用,并覆盖你的操作。如果它的终端和高优先级,它会清除。
angular.module('soQuestion', [])
.directive('example', function () {
return {
priority: 1000,
terminal : true,
compile: function (tElement, tAttrs) {
if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
tElement.attr('foo', 'prefix-' + tAttrs.foo);
console.log(tElement.attr('foo'), tElement[0]);
}
return function(){};
}
};
})
.controller('controller', function($scope) {
$scope.value = 'something';
});
因为这打破了{{}}
我会考虑手动编译attr。
答案 1 :(得分:0)
angular.module('soQuestion', [])
.directive('example', function () {
return {
compile: function (tElement, tAttrs) {
if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
// Change the tAttrs hash instead of the element itself
tAttrs.foo = 'prefix-' + tAttrs.foo;
// Change the element too, in case no interpolation is present
tElement.attr('foo', tAttrs.foo);
console.log(tElement.attr('foo'));
}
}
};
})
说明:interpolate
指令确实检查属性值的变化。但是它不再在DOM节点本身上查看,而是在tAttrs
哈希上。
旧的悲观回答:
我认为不可能达到预期的效果。
查看Angular的源代码,collectDirectives
将影响某个节点的指令列表放在一起。收集它们各自的compile
函数,然后按优先级排序。问题是{{}}
的编译函数然后绑定到keyword_{{value}}
并且不受example
指令的影响。