4

我在 AngularJS 1.2 中创建了一个过滤器,它使用ShowdownJS将Markdown内容解析为 HTML:

App.filter('markdown', function( $sce ) {
    var converter = new Showdown.converter();
    return function (value) {
        var html = converter.makeHtml(value);
        return $sce.trustAsHtml(html);
    };
});

模板中的绑定是使用ng-bind-html完成的。这个接收到最终的 HTML 内容,因此必须显示内容:

<div ng-bind-html="post.content | markdown"></div>

过滤器有效,但我在控制台中收到此错误,因为它返回 $sce 服务并且它应该只返回已解析的HTML 字符串

10 $digest() iterations reached. Aborting!

如何在过滤器中避免这种情况?我找不到任何可以从 $sce 服务中提取转义 html 的方法。

编辑:如果我在配置中禁用清理服务,即使代码保持完全相同,我也不会收到此错误。

$sceProvider.enabled(false);
4

4 回答 4

3

好的,经过一番调查,我发现问题出在实例上。每次您的过滤器触发时,您都会返回另一个实例。然后 ng-bind-html 观察者无限触发。

演示

我添加了所有受信任值的缓存:

app.filter('markdown', ['$sce', function( $sce ) {
    var converter = new Showdown.converter();
    var converted = {};

    return function (value) {
      if(converted.hasOwnProperty(value)) {
        return converted[value];
      }

      var html = converter.makeHtml(value);
      var trusted = converted[value] = $sce.trustAsHtml(html);
      return trusted;
    };
}]); 
于 2013-10-11T09:51:33.723 回答
1

我认为这与ngBindHtmlDirective观察它并在该值上调用 $sce.getTrustedHtml 有关。您可以通过避免$sce和使用自己的指令(plnkr)来解决它:

App.directive('simpleHtml', function() {
  return function(scope, element, attr) {
    scope.$watch(attr.simpleHtml, function (value) {
      element.html(scope.$eval(attr.simpleHtml));
    })
  };
})
于 2013-10-10T21:42:20.420 回答
0

尝试

return $sce.trustAsHtml(html).toString();
于 2013-10-10T23:44:23.043 回答
0

当我遇到这个错误时,我不小心在对象上使用了过滤器而不是字符串。

于 2014-11-20T22:10:39.503 回答