使用ng-bind-html进行ng-repeat作为标记前和标记后

时间:2016-05-02 09:17:46

标签: angularjs ng-bind-html ngsanitize

我有一个包含多个对象的数组,类似于:

[ 
  { title: 'abc', 'pre': '<div class="class1"><div class="class2">', 'post': '</div>' },
  { title: 'def', 'pre': <div class="class3">', 'post': '</div>' },
  { title: 'ghi', 'pre': '<div class="class3">', 'post': '</div></div>' }
]

<div ng-repeat="item in myVar">
  <div ng-bind-html="item.pre" />{{ item.title }}<div ng-bind-html="item.post" />
</div>

以上不起作用(我必须在一个中打开两个div,并在该数组中关闭另外两个项目,如上图所示)。问题是ng-bind-html需要绑定到一个我无法使用的元素,过滤器也不能工作:

<div ng-repeat="item in myVar">
  {{ item.pre | trust }}{{ item.title }}{{ item.post | trust }}
</div>

angular.module('myModule').filter('trust', ['$sce',function($sce) {
  return function(value, type) { return $sce.trustAsHtml; }
}]);

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您必须执行连接预览,相信(或打开ngSanitize,可能更好),然后注入它。

据我所知,没有办法以您尝试的方式注入部分HTML元素。

在您的控制器中:

$scope.items = [...];

for (var i = 0; i < $scope.items.length; i++) {
    var e = $scope.items[i];

    e.concatenated = $sce.trustAsHtml(e.pre + e.title + e.post);
}

然后在你看来:

<div ng-repeat="item in items">
    <div ng-bind-html="item.concatenated" />
</div>

当然,您可能希望启用ngSanitize,以避免e.title出现任何问题。也就是说,如果有人输入了<script>alert('ahh!')</script>的标题,那最终会被信任。

由于编写ngBindHtml的方式,您的版本无效:

var ngBindHtmlDirective = ['$sce', '$parse', '$compile', function($sce, $parse, $compile) {
  return {
    restrict: 'A',
    compile: function ngBindHtmlCompile(tElement, tAttrs) {
      var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml);
      var ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function getStringValue(value) {
        return (value || '').toString();
      });
      $compile.$$addBindingClass(tElement);

      return function ngBindHtmlLink(scope, element, attr) {
        $compile.$$addBindingInfo(element, attr.ngBindHtml);

        scope.$watch(ngBindHtmlWatch, function ngBindHtmlWatchAction() {
          // we re-evaluate the expr because we want a TrustedValueHolderType
          // for $sce, not a string
          element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || '');
        });
      };
    }
  };
}];

它使用element.html(...)进行注入,这需要一个完整的HTML元素。