Jak utworzyć filtr angularjs, który generuje HTML

91

Po przeczytaniu poradnika AngularJS krok 9 stworzyłem własny filtr AngularJS, który powinien konwertować dane boolowskie do html.

Oto mój kod filtra:

angular.module('phonecatFilters', []).filter('iconify', function () { // My custom filter
    return function (input) {
        return input ? '<i class="icon-ok"></i>' : '<i class="icon-remove"></i>';
    }
});

Oto mój kod HTML:

<dt>Infrared</dt>
  <dd>{{phone.connectivity.infrared | iconify }}"></dd>

Problem w tym, że borwser wyświetla zwracaną wartość dosłownie jako:

<i class="icon-ok"></i>

nie jako ikony (lub wyrenderowany html), które powinny się pojawić.

Oto przykład JSFiddle

Myślę, że podczas tego procesu następuje pewna dezynfekcja.

Czy można wyłączyć tę sanityzację dla tego konkretnego filtra?

Wiem również, jak wyświetlać ikony, nie zwracając wyjścia HTML z filtru, a raczej po prostu „ok” lub „usuń” tekst, który mogę następnie zastąpić:

<i class="icon-{{phone.connectivity.infrared | iconify}}"><i>

ale nie tego chcę.

Pavel Kostenko
źródło

Odpowiedzi:

112

Powinieneś użyć ng-bind-htmldyrektywy (wymagaj zaimportowania modułu sanitize i pliku js): https://docs.angularjs.org/api/ng/directive/ngBindHtml

<span ng-bind-html='phone.connectivity.infrared | iconify'></span>

Musisz także zaimportować CSS ( chyba Bootstrap ), aby móc zobaczyć ikonę, gdy działa.

Podałem działający przykład .

Guillaume86
źródło
2
Cóż, to jedyny sposób, jaki znam, aby wyprowadzić surowy kod HTML z angularJS, a to powiązanie jest dozwolone tylko dla atrybutów, więc nie masz dużego wyboru, możesz napisać własną dyrektywę, która akceptuje komentarze lub powiązania elementów, pobrać kod źródłowy bind- html jako punkt wyjścia: github.com/angular/angular.js/blob/master/src/ngSanitize/…
Guillaume86
2
Dyrektywa może być tutaj najprzyjemniejszym rozwiązaniem <check-icon ng: model = 'phone.connectivity.infrared'> </check-icon>, ale nie jest krótsze niż twoje rozwiązanie;)
Guillaume86
7
Należy pamiętać, że aby to angular-sanitize.jszadziałało , należy dołączyć plik. Jeśli chcesz zrobić to samo bez dołączania tej dodatkowej biblioteki, możesz użyć ng-bind-html-unsafedyrektywy.
nwinkler
4
angular 2.x opuszcza ng-html-bind-unsafei wymaga, aby zawartość html była wyraźnie oznaczona jako `
`
1
Powinien istnieć domyślny filtr html_safe:{{myContent | myFilter | html_safe}}
Augustin Riedinger
17

chyba że źle to czytam, podchodzisz w niewłaściwy sposób

Myślę, że ng-class to dyrektywa, której potrzebujesz do tej pracy i jest bezpieczniejsza niż renderowanie do atrybutu class.

w twoim przypadku po prostu dodaj łańcuch obiektu z ciągami znaków id jako klasą i wartością jako oszacowanym wyrażeniem

<i ng-class="{
'icon-ok':!phone.connectivity.infrared,
'icon-remove':phone.connectivity.infrared
}"></i>'

na marginesie, powinieneś używać tylko dyrektyw (wbudowanych i niestandardowych) do manipulowania html / dom, a jeśli potrzebujesz bardziej złożonego renderowania html, powinieneś zamiast tego spojrzeć na dyrektywę

Gerard
źródło
Dobre rozwiązanie. Albo trochę prościej: <i ng-class="phone.connectivity.infrared ? 'icon-ok' : 'icon-remove'"></i>
Grid Trekkor
12

Wypróbuj ten filtr

filter('trust', ['$sce',function($sce) {
  return function(value, type) {
    return $sce.trustAs(type || 'html', value);
  }
}]);

wymaga kanciastego odkażania

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

Gist Link

Vikrant Mahajan
źródło