【问题标题】:ng-repeat with ng-bind-html as pre and post-markupng-repeat 使用 ng-bind-html 作为 pre 和 post-markup
【发布时间】:2016-05-02 09:17:45
【问题描述】:

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

[ 
  { 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; }
}]);

有什么想法吗?

【问题讨论】:

    标签: angularjs ng-bind-html ngsanitize


    【解决方案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 出现任何问题。也就是说,如果有人输入了 &lt;script&gt;alert('ahh!')&lt;/script&gt; 的标题,那么它最终会被信任。


    由于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元素。

    【讨论】:

    • 我使用 ng-sanitize,是的。串联真的是唯一的方法吗?
    • @chrney 是的,据我所知。请参阅我的编辑以了解一些原因。 可能有一个解决方法,但老实说,我很想坚持串联。如果需要,您可以编写一个指令来执行该连接。
    猜你喜欢
    • 1970-01-01
    • 2015-02-09
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多