Angular jquery插件对ajax调用的数据进行包装



我试图写一个基本的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

最新更新