我试图写一个基本的jquery插件包装指令,但我一直面临的问题是,当插件在链接函数内调用时,angular没有渲染绑定的数据。
从html:<my-syntax ng-bind="snippet.code"></my-syntax>
指令:
angular.module('myDemo').directive('mySyntax', function($timeout) {
return {
restrict: 'E',
replace: true,
template: '<pre><code></code></pre>',
link: function(scope, element) {
// this timeout seems brittle, need better solution
$timeout(function() {
element.each(function(i, e) { hljs.highlightBlock(e) });
}, 50);
}
});
highlightjs插件依赖于元素的内容,但由于它来自我的"片段。代码范围绑定,该值来自ajax调用,jquery插件正在对尚未呈现的内容执行。我已经"解决"了这个问题,将jqueryPlugin调用包装在$timeout中,时间为50ms,但这似乎非常脆弱。我也尝试过使用隔离的作用域,并在作用域变量的监视中包装jqueryPlugin调用,但在这种情况下,没有任何渲染(没有发生js错误)。我认为这是一种非常常见的指令类型,但我还没有找到解决这个问题的方法。
尝试:
<my-syntax code="snippet.code"></my-syntax>
指令:
angular.module('myDemo').directive('mySyntax', function($timeout) {
return {
restrict: 'E',
replace: true,
template: '<pre><code>{{code}}</code></pre>',
scope: {
code: '='
},
link: function(scope, element) {
scope.$watch('code', function() {
element.each(function(i, e) { hljs.highlightBlock(e) });
}, 50);
}
});
你的第二次尝试几乎是正确的。
问题是第一次执行监视器的侦听器函数时,新旧值都是未定义的。这意味着highlightBlock
函数将运行两次,它无法处理:
你可以使用highlightBlock来突出显示动态插入的块进入页面。只是要确保你不会重复两次突出街区。
的例子:
return {
restrict: 'E',
replace: true,
template: '<pre><code>{{code}}</code></pre>',
scope: {
code: '='
},
link: function(scope, element) {
var watchExpression = function() {
return scope.code;
};
var listener = function(newValue, oldValue) {
if (newValue === oldValue) return;
element.each(function(i, e) {
hljs.highlightBlock(e)
});
unregister();
};
var unregister = scope.$watch(watchExpression, listener);
}
}
因为它不能运行两次,所以我让listener
函数在完成后注销监视器。
另外,$watch
中的第三个参数是一个布尔值,用于设置是否为深度监视。在您的示例中,您正在传递50
,但我怀疑这是$timeout
尝试的复制和粘贴错误。
http://plnkr.co/edit/6j0BMxjNX88GchXCIlJq?p=preview