我整理了一个最能说明我的问题的 plunker。
我正在尝试编写一个简单的指令,该指令将从指令中更新包含的 html。
例如,我希望拥有:
<make-bold>Foo *bar* {{something}}</make-bold>
生成为
<span>Foo <b>bar</b> somevalue<span>
plunker 上的示例工作正常,但我无法弄清楚如何获取包含内容更改的通知(监视)。在示例中,尝试选择不同的项目(通过单击它们),您会注意到"已处理"不会更新。
我很确定问题是传递给链接函数的元素不会更新,但它的内容会更新,因此无法观看。
命令
app.directive('makeBold', function($interpolate, $timeout, $compile)
{
var regex = new RegExp("\*(.+?)\*", 'g');
var replace = "<b>$1</b>";
return {
restrict: 'E',
transclude: true,
replace: true,
template: '<span ng-transclude></span>',
link: function (scope, element, attrs)
{
scope.$watch(
function() {
// *** What do I need to watch here? ***
return element;
},
function(n, o) {
var text = $interpolate(element.text())(scope);
var newContent = text.replace(regex, replace);
$timeout(function() { element.html(newContent); });
});
}
};
});
模板
<div ng-show="selected">
<h1>{{selected.name}}</h1>
<p><i>Original:</i> {{selected.detail}}</p>
<p><i>Processed:</i> <make-bold>{{selected.detail}}</make-bold></p>
</div>
(注意:我实际上并不想制定"粗体"指令,但这说明了我遇到的问题。
这是一个工作 plunker
这个并不明显,非常具有挑战性。我必须查看角度.js源代码,以完全了解包含的内容所在的位置以及角度对内插文本的作用。
这里的诀窍是禁用角度插值并手动使用$interpolate。
addTextInterpolateDirective 函数在编译中.js负责插值 ( {{ }} ) 的魔术绑定。
稍后,我将通过详细的解释来更新这个答案。
溶液:
app.directive('makeBold', function( $interpolate ) {
var regex = new RegExp("\*(.+?)\*", 'g');
var replace = "<b>$1</b>";
return {
restrict: 'E',
scope: true,
compile: function (tElem, tAttrs) {
var interpolateFn = $interpolate(tElem.html(), true);
tElem.empty(); // disable automatic intepolation bindings
return function(scope, elem, attrs){
scope.$watch(interpolateFn, function (value) {
var newContent = value.replace(regex, replace);
elem.html(newContent);
});
}
}
};
});