Highlight.js 在 AngularJS SPA 不工作

Highlight.js in AngularJS SPA doesn't work

我有一个 AngularJS SPA,可以将文章加载到视图中。有些文章有代码示例,我想用highlight.js突出显示

在下面的示例中,我模拟了一个获取请求,因为这就是我在实际应用程序中加载动态内容的方式。 $scope.test 与我的实际应用程序返回的内容非常相似;一些常规 HTML 打印出来,其中包括代码示例。

我的问题:它似乎真的不起作用。

具体来说,没有突出显示任何内容。在我看来,我好像缺少一个 init 或其他东西...... Halp?

我也试过 <div hljs/> 结果相同(没有)。没有控制台错误。

提供了在模板中使用ng-model的解决方案。但是,我没有在任何地方使用 ng-model。

编辑:我对示例代码进行了一些更改以进一步解释问题。

这是我的应用程序(已简化):

var app = angular.module('app', ['ngSanitize']);

app.controller('ctrl', ['$scope', '$http',
    function($scope, $http) {
        "use strict";
        $http.get('/echo/html').then(function successCallback(response) {
            $scope.title = 'Some Title';
            $scope.metaStuff = 'Written by Awesome MacFluffykins';
            $scope.articleBody = '<p>Here\'s an example of a simple SQL SELECT:</p><pre><code class="sql" highlight>SELECT * FROM table WHERE user = \'1\'</code></pre>';
        }, function errorCallback(response) {
            console.log("Error: %d %s", response.code, response.message);
        });
    }
]);

这是我的 HTML:

<div ng-app="app" ng-controller="ctrl">
    <h2>{{ title }}</h2>
    <p><small>{{ metaStuff }}</small></p>
    <div ng-bind-html="articleBody"></div>
</div>

最后 jsFiddle.

Fiddle https://jsfiddle.net/vg75ux6v/

var app = angular.module('app', ['hljs', 'ngSanitize']);

app.controller('ctrl', ['$scope', '$http',
    function($scope, $http) {
        "use strict";
        $http.get('/echo/html').then(function successCallback(response) {
            $scope.test = '<h2>Here\'s some code:</h2><pre><code hljs class="sql">SELECT * FROM table WHERE user = \'1\'</code></pre>';
        }, function errorCallback(response) {
            console.log("Error: %d %s", response.code, response.message);
        });
    }
]).directive('compile', ['$compile', function ($compile) {
    return function(scope, element, attrs) {
        scope.$watch(
            function(scope) {
                return scope.$eval(attrs.compile);
            },
            function(value) {
                element.html(value);

                $compile(element.contents())(scope);
            }
        );
    };
}]);

在我看来,最好使用指令来进行这样的 DOM 操作。通过 ng-model(您也可以使用另一个属性)和指令中的 运行 HLJS 传递您的源代码。由于您使用异步方法为范围提供值,因此您需要使用 $watch 来捕获该值,然后使用 运行 HLJS:

HTML:

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

指令:

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

工作 JSFiddle:https://jsfiddle.net/1qy0j6qk/