2016-05-02 2 views
1

У меня есть массив с несколькими объектами, подобный этому:нг-повтор с нг-затруднительное-HTML, как до и после разметки

[ 
    { 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> 

выше не работает (я должен открыть два Див-х в один и закрыть в двух других элементах в этом массиве, как показано выше). Проблема заключается в том, что нг-связывать-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

Вам необходимо выполнить предварительный просмотр конкатенации, полагая, что (или включите 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 элемент.

+0

Я использую ng-sanitize, да. Единственный способ конкатенации? – chrney

+0

@chrney Да, насколько я знаю. См. Мое редактирование для небольшого количества причин. Там может быть обходной путь, но, честно говоря, у меня возникнет соблазн придерживаться конкатенации. Вы можете написать директиву для выполнения этой конкатенации, если потребуется. –

Смежные вопросы