Comment créer un filtre angularjs qui génère du HTML

90

Après avoir lu l' étape 9 du didacticiel AngularJS, j'ai créé mon propre filtre AngularJS, qui devrait convertir les données booléennes en html.

Voici mon code de filtre:

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

Voici mon code HTML:

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

Le problème est que borwser affiche littéralement la valeur renvoyée comme suit:

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

pas comme des icônes (ou rendu html) qui devraient apparaître.

Voici l'exemple de JSFiddle

Je pense qu'une certaine désinfection se produit pendant ce processus.

Est-il possible de désactiver cette désinfection pour ce filtre spécifique?

De plus, je sais comment afficher les icônes en ne renvoyant pas la sortie HTML du filtre, mais plutôt simplement en `` ok '' ou en `` supprimant '' du texte que je peux ensuite remplacer:

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

mais ce n'est pas ce que je veux.

Pavel Kostenko
la source

Réponses:

112

Vous devez utiliser la ng-bind-htmldirective (nécessite d'importer le module sanitize et le fichier js): https://docs.angularjs.org/api/ng/directive/ngBindHtml

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

Vous devez également importer le CSS ( Bootstrap je suppose) pour pouvoir voir l'icône quand cela fonctionne.

J'ai fourni un exemple de travail .

Guillaume86
la source
2
Eh bien, c'est le seul moyen que je connaisse de générer du HTML brut avec angularJS et cette liaison n'est autorisée que sur les attributs, vous n'avez donc pas beaucoup de choix, vous pouvez écrire votre propre directive qui accepte les commentaires ou les liaisons d'éléments, prenez le code source de bind- html pour un point de départ: github.com/angular/angular.js/blob/master/src/ngSanitize/…
Guillaume86
2
Une directive peut-être la meilleure solution ici <check-icon ng: model = 'phone.connectivity.infrared'> </check-icon> mais ce n'est pas vraiment plus court que votre solution;)
Guillaume86
7
Une chose à noter est que vous devez inclure le angular-sanitize.jsfichier pour que cela fonctionne. Si vous souhaitez faire de même sans inclure cette bibliothèque supplémentaire, vous pouvez utiliser la ng-bind-html-unsafedirective.
nwinkler
4
angular 2.x abandonne ng-html-bind-unsafeet nécessite que le contenu html soit explicitement marqué comme `` sûr '' - voir: docs.angularjs.org/api/ng.$sce#Example
hooblei
1
Il devrait y avoir un filtre par défaut html_safe:{{myContent | myFilter | html_safe}}
Augustin Riedinger
17

à moins que je ne le lise mal, vous vous approchez de la mauvaise manière

Je pense que ng-class est la directive dont vous avez besoin pour ce travail et est plus sûr que le rendu en attribut de classe.

dans votre cas, ajoutez simplement une chaîne d'objet avec les chaînes d'identifiant comme classe et la valeur comme expression évaluée

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

Par ailleurs, vous ne devez utiliser que des directives (intégrées et personnalisées) pour manipuler html / dom et si vous avez besoin d'un rendu html plus complexe, vous devriez plutôt regarder la directive

Gérard
la source
Bonne solution. Ou fait un peu plus simple: <i ng-class="phone.connectivity.infrared ? 'icon-ok' : 'icon-remove'"></i>
Grid Trekkor
11

Essayez ce filtre

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

nécessite une désinfection angulaire

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

Lien Gist

Vikrant Mahajan
la source