Cómo crear un filtro angularjs que genera HTML


90

Después de leer el paso 9 del tutorial de AngularJS , he creado mi propio filtro AngularJS, que debería convertir datos booleanos en html.

Aquí está mi código de filtro:

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

Aquí está mi código HTML:

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

El problema es que borwser muestra el valor devuelto literalmente como:

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

no como iconos (o html renderizado) que deberían aparecer.

Aquí está el ejemplo de JSFiddle

Creo que se produce algo de desinfección durante este proceso.

¿Es posible desactivar esta desinfección para este filtro específico?

También sé cómo mostrar iconos al no devolver la salida HTML del filtro, sino simplemente 'aceptar' o 'eliminar' el texto que luego puedo sustituir por:

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

pero esto no es lo que quiero.

Respuestas:


112

Debe usar la ng-bind-htmldirectiva (requiere importar el módulo de desinfección y el archivo js): https://docs.angularjs.org/api/ng/directive/ngBindHtml

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

También necesita importar el CSS ( Bootstrap , supongo) para poder ver el icono cuando funciona.

Proporcioné un ejemplo práctico .


2
Bueno, es la única forma que conozco de generar html sin procesar con angularJS y este enlace solo está permitido en atributos, por lo que no tiene muchas opciones, puede escribir su propia directiva que acepte comentarios o enlaces de elementos, tome el código fuente de bind- html para un punto de partida: github.com/angular/angular.js/blob/master/src/ngSanitize/…
Guillaume86

2
Una directiva tal vez sea la mejor solución aquí <check-icon ng: model = 'phone.connectivity.infrared'> </check-icon> pero no es realmente más corta que su solución;)
Guillaume86

7
Una cosa a tener en cuenta es que debe incluir el angular-sanitize.jsarchivo para que esto funcione. Si desea hacer lo mismo sin incluir esta biblioteca adicional, puede usar la ng-bind-html-unsafedirectiva.
nwinkler

4
angular 2.xy ng-html-bind-unsaferequiere que el contenido html se marque explícitamente como 'seguro'; consulte: docs.angularjs.org/api/ng.$sce#Example
hooblei

1
Debe haber un filtro predeterminado html_safe:{{myContent | myFilter | html_safe}}
Augustin Riedinger

17

a menos que lo esté leyendo mal, te estás acercando por el camino equivocado

Creo que ng-class es la directiva que necesita para este trabajo y es más segura que la representación en el atributo de clase.

en su caso, simplemente agregue la cadena de objeto con las cadenas de identificación como la clase y el valor como la expresión evaluada

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

en una nota al margen, solo debe usar directivas (integradas y personalizadas) para manipular html / dom y si necesita un render html más complejo, debe mirar la directiva en su lugar


Buena solución. O hecho un poco más simple: <i ng-class="phone.connectivity.infrared ? 'icon-ok' : 'icon-remove'"></i>
Grid Trekkor

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.