Angular JS:检测 ng-bind-html 是否完成加载然后突出显示代码语法

Angular JS: Detect if ng-bind-html finished loading then highlight code syntax

我正在使用 ng-bind-html 来绑定从数据库中获取的数据。

<p ng-bind-html="myHTML"></p>   


app.controller('customersCtrl', function($scope, $http, $stateParams) {
    console.log($stateParams.id);
    $http.get("api link"+$stateParams.id)
    .then(function(response) {
      $scope.myHTML = response.data.content;

        // this will highlight the code syntax
        $('pre code').each(function(i, block) {
            hljs.highlightBlock(block);
        });
    });
});

当数据显示在屏幕上时,我要运行

$('pre code').each(function(i, block) {
      hljs.highlightBlock(block);
});

用于突出显示数据中的代码语法但不是突出显示。 (我使用 highlight library in CKEditor 来突出显示代码语法)

如果我在1秒后延迟加载高亮代码,它会起作用,但我认为这不是一个好的解决方案

setTimeout(function () {
    $('pre code').each(function(i, block) {
        hljs.highlightBlock(block);
    });
  }, 1000);

我想也许 ng-bind-html 完成之前的高亮代码 运行。

=== 更新
正如某些人推荐的那样,我正在使用延迟时间为 0 的 $timeout。但是,有时候网速慢,页面加载慢的时候,代码不会高亮。

$scope.myHTML = response.data.content;
$timeout(function() {
  $('pre code').each(function(i, block) {
      hljs.highlightBlock(block);
  });
}, 0);

如您所知,如果没有超时,语句将异步执行 $('pre code') 将为空,因为 DOM 仍未呈现。 同样使用 $timeout 而不是 setTimeout。

这就是指令派上用场的地方。为什么不自己附加 HTML 然后 运行 荧光笔?

模板:

<div ng-model="myHTML" highlight></div>

指令:

.directive('highlight', [
    function () {
        return {
            replace: false,
            scope: {
                'ngModel': '='
            },
            link: function (scope, element) {
                element.html(scope.ngModel);
                var items = element[0].querySelectorAll('code,pre');
                angular.forEach(items, function (item) {
                    hljs.highlightBlock(item);
                });

            }
        };
    }
]);

示例:http://plnkr.co/edit/ZbcNgfl6xL2QDDqL9cKc?p=preview

事情是这样的:

  1. 您更新 $scope.myHTML
  2. 你运行你的jQueryeach()循环
  3. digest cycle 运行 和您的模板已更新

请注意摘要循环 运行s 你的 jQuery each() 循环之后——或者更具体地说,在你的 $http回调函数结束运行ning.

这意味着在循环完成之前,控制器中 $scope.myHTML 的值不会应用于 ng-bind-html 指令。

为了克服这个问题,您可以使用 Angular 的 $timeout 服务而不是本机浏览器 setTimeout() 方法。默认情况下,$timeout 将在下一个摘要周期调用回调函数,这意味着它将 运行 在对 $scope.myHTML 的更改应用到 ng-bind-html 指令(只要在调用 $timeout()) 之前更新 $scope.myHTML

工作示例:JSFiddle