So erstellen Sie einen AngularJS-Filter, der HTML ausgibt

90

Nachdem ich das AngularJS-Tutorial Schritt 9 gelesen habe, habe ich meinen eigenen AngularJS-Filter erstellt, der boolesche Daten in HTML konvertieren soll.

Hier ist mein Filtercode:

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

Hier ist mein HTML-Code:

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

Das Problem ist, dass der Borroser den zurückgegebenen Wert buchstäblich wie folgt anzeigt:

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

nicht als Symbole (oder gerendertes HTML), die angezeigt werden sollen.

Hier ist ein JSFiddle-Beispiel

Ich denke, dass während dieses Prozesses eine gewisse Desinfektion auftritt.

Ist es möglich, diese Desinfektion für diesen bestimmten Filter auszuschalten?

Außerdem weiß ich, wie Symbole angezeigt werden, indem keine HTML-Ausgabe vom Filter zurückgegeben wird, sondern nur "OK" oder "Entfernen" von Text, den ich dann ersetzen kann:

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

aber das will ich nicht.

Pavel Kostenko
quelle

Antworten:

112

Sie sollten die ng-bind-htmlDirektive verwenden (zum Importieren des Desinfektionsmoduls und der JS-Datei erforderlich): https://docs.angularjs.org/api/ng/directive/ngBindHtml

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

Sie müssen auch das CSS ( Bootstrap, denke ich) importieren , um das Symbol sehen zu können, wenn es funktioniert.

Ich habe ein funktionierendes Beispiel geliefert .

Guillaume86
quelle
2
Nun, es ist die einzige Möglichkeit, die ich kenne, um rohes HTML mit angleJS auszugeben. Diese Bindung ist nur für Attribute zulässig. Sie haben also keine große Auswahl. Sie können eine eigene Direktive schreiben, die Kommentare oder Elementbindungen akzeptiert. Nehmen Sie den Quellcode von bind-. HTML für einen Ausgangspunkt: github.com/angular/angular.js/blob/master/src/ngSanitize/…
Guillaume86
2
Eine Direktive ist vielleicht die schönste Lösung hier <check-icon ng: model = 'phone.connectivity.infrared'> </ check -icon>, aber sie ist nicht wirklich kürzer als Ihre Lösung;)
Guillaume86
7
Eine Sache zu beachten ist, dass Sie die angular-sanitize.jsDatei einschließen müssen, damit dies funktioniert. Wenn Sie dasselbe tun möchten, ohne diese zusätzliche Bibliothek einzuschließen, können Sie die ng-bind-html-unsafeDirektive verwenden.
Nwinkler
4
Angular 2.x wird gelöscht ng-html-bind-unsafeund erfordert, dass der HTML-Inhalt explizit als "sicher" gekennzeichnet wird - siehe: docs.angularjs.org/api/ng.$sce#Example
hooblei
1
Es sollte einen Standardfilter html_safe geben:{{myContent | myFilter | html_safe}}
Augustin Riedinger
17

Wenn ich es nicht falsch lese, nähern Sie sich auf die falsche Weise

Ich denke, ng-class ist eine Direktive, die Sie für diesen Job benötigen, und ist sicherer als das Rendern in Klassenattribute.

In Ihrem Fall fügen Sie einfach eine Objektzeichenfolge mit den ID-Zeichenfolgen als Klasse und dem Wert als ausgewertetem Ausdruck hinzu

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

Nebenbei bemerkt, Sie sollten nur Direktiven (integriert und benutzerdefiniert) verwenden, um HTML / Dom zu bearbeiten. Wenn Sie ein komplexeres HTML-Rendering benötigen, sollten Sie stattdessen die Direktive betrachten

Gerard
quelle
Gute Lösung. Oder etwas einfacher gemacht: <i ng-class="phone.connectivity.infrared ? 'icon-ok' : 'icon-remove'"></i>
Grid Trekkor
11

Probieren Sie diesen Filter aus

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

erfordert Winkel-Desinfektion

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

Hauptlink

Vikrant Mahajan
quelle