Enlace HTML angular


Estoy escribiendo una aplicación Angular y tengo una respuesta HTML que quiero mostrar.

¿Cómo hago eso? Si simplemente utilizo la sintaxis de enlace {{myVal}} codifica todos los caracteres HTML (por supuesto).

De alguna manera necesito enlazar el html interno de un div al valor de la variable.

Author: Narendra Jadhav, 2015-07-21

15 answers

La sintaxis correcta es ahora la siguiente:

<div [innerHTML]="theHtmlString"></div>

Trabajando en 6.1.9

Referencia de la documentación

 877
Author: prolink007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-03 19:11:20

Angular 2.0.0 y Angular 4.0.0 final

Para contenido seguro solo

<div [innerHTML]="myVal"></div>

DOMSanitizer

El HTML potencialmente inseguro debe marcarse explícitamente como de confianza utilizando Angulars DOM sanitizer para que no elimine las partes potencialmente inseguras del contenido

<div [innerHTML]="myVal | safeHtml"></div>

Con un tubo como

@Pipe({name: 'safeHtml'})
export class Safe {
  constructor(private sanitizer:DomSanitizer){}

  transform(style) {
    return this.sanitizer.bypassSecurityTrustHtml(style);
    //return this.sanitizer.bypassSecurityTrustStyle(style);
    // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
  }
}

Véase también En RC.1 algunos estilos no se pueden agregar usando sintaxis de enlace

Y documentos: https://angular.io/api/platform-browser/DomSanitizer

Advertencia de Seguridad

Confiar en el HTML añadido por el usuario puede suponer un riesgo para la seguridad. El anterior mencionado docs estado:

Llamar a cualquiera de las API bypassSecurityTrust... deshabilita la desinfección integrada de Angular para el valor pasado. Compruebe y audite cuidadosamente todos los valores y rutas de código que entran en esta llamada. Asegúrese de que todos los datos de usuario estén correctamente escapados para este contexto de seguridad. Para más detalles, consulte la Guía de seguridad .

Marcado angular

Algo así como

class FooComponent {
  bar = 'bar';
  foo = `<div>{{bar}}</div>
    <my-comp></my-comp>
    <input [(ngModel)]="bar">`;

Con

<div [innerHTML]="foo"></div>

No hará que Angular procese nada específico de Angular en foo. Angular reemplaza el marcado específico de Angular en el tiempo de compilación con código generado. El marcado agregado en tiempo de ejecución no será procesado por Angular.

Para agregar HTML que contenga marcas específicas de Angular (enlace de propiedades o valores, componentes, directivas, canalizaciones,...) se es necesario agregar el módulo dinámico y compilar componentes en tiempo de ejecución. Esta respuesta proporciona más detalles ¿Cómo puedo usar/crear una plantilla dinámica para compilar un componente dinámico con Angular 2.0?

 188
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-07 09:52:04

[innerHtml] es una gran opción en la mayoría de los casos, pero falla con cadenas realmente grandes o cuando necesita un estilo codificado en html.

Me gustaría compartir otro enfoque:

Todo lo que necesita hacer, es crear un div en su archivo html y darle algún id:

<div #dataContainer></div>

Luego, en su componente Angular 2, cree una referencia a este objeto (TypeScript aquí):

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}

Luego simplemente use la función loadData para agregar algo de texto al elemento html.

Es solo una forma en que lo haría hacerlo utilizando javascript nativo, pero en entorno Angular. No lo recomiendo, porque hace que el código sea más desordenado, pero a veces no hay otra opción.

Ver también Angular 2-innerHTML styling

 124
Author: Piotrek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-19 08:17:16

El [email protected]:

El enlace html no funcionará cuando se use un {{interpolation}}, use una" expresión " en su lugar:

No Válido

<p [innerHTML]="{{item.anleser}}"></p>

- > lanza un error (Interpolación en lugar de la expresión esperada)

Correcto

<p [innerHTML]="item.anleser"></p>

-> este es el camino correcto.

Puede agregar elementos adicionales a la expresión, como:

<p [innerHTML]="'<b>'+item.anleser+'</b>'">></p>

Pista

HTML agregado usando [innerHTML] (o agregado dinámicamente por otros medios como element.appenChild() o similar)no será procesado por Angular de ninguna manera excepto la desinfección para fines de seguridad.
Estas cosas solo funcionan cuando el HTML se agrega estáticamente a una plantilla de componentes. Si necesita esto, puede crear un componente en tiempo de ejecución como se explica en ¿Cómo puedo usar/crear plantilla dinámica para compilar un componente dinámico con Angular 2.0?

 25
Author: jvoigt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-23 14:18:29

Esto funciona para mí: <div innerHTML = "{{ myVal }}"></div> (Angular2, Alfa 33)

De acuerdo con otro SO: Insertando HTML desde el servidor en el DOM con angular2 (manipulación general del DOM en Angular2), "inner-html" es equivalente a "ng-bind-html" en Angular 1.X

 14
Author: Fan Li,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:01

Usar [innerHTML] directamente sin usar el desinfectante DOM de Angular no es una opción si contiene contenido creado por el usuario. La tubería safeHtml sugerida por @GünterZöchbauer en su respuesta es una forma de desinfectar el contenido. La siguiente directiva es otra:

import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
  SimpleChanges } from '@angular/core';

// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
  @Input() safeHtml: string;

  constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}

  ngOnChanges(changes: SimpleChanges): any {
    if ('safeHtml' in changes) {
      this.elementRef.nativeElement.innerHTML =
        this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
    }
  }
}

Se utilizará

<div [safeHtml]="myVal"></div>
 14
Author: Rene Hamburger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:46

Solo para hacer una respuesta completa, si su contenido html está en una variable de componente, también podría usar:

<div [innerHTML]=componementVariableThatHasTheHtml></div>
 9
Author: Serj Sagan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-31 05:43:42

Me disculpo si me estoy perdiendo el punto aquí, pero me gustaría recomendar un enfoque diferente:

Creo que es mejor devolver datos sin procesar de su aplicación del lado del servidor y vincularlos a una plantilla en el lado del cliente. Esto hace que las solicitudes sean más ágiles, ya que solo devuelve json de su servidor.

Para mí no parece que tenga sentido usar Angular si todo lo que estás haciendo es buscar html del servidor e inyectarlo "tal cual" en el DOM.

Lo sé Angular 1.x tiene un enlace html, pero todavía no he visto una contraparte en Angular 2.0. Sin embargo, podrían agregarlo más tarde. De todos modos, todavía consideraría una api de datos para su aplicación Angular 2.0.

Aquí tengo algunas muestras con un simple enlace de datos si está interesado: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

 7
Author: TGH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-21 22:17:44

Simplemente use el atributo [innerHTML] en su HTML , algo como esto a continuación:

<div [innerHTML]="myVal"></div>

Alguna vez tuvo propiedades en su componente que contienen algún marcado html o ¿entidades que necesitas mostrar en tu plantilla? El tradicional la interpolación no funcionará, pero el enlace de propiedades innerHTML llega a rescate.

Usando {{myVal}} NO funciona como se esperaba! This won't recoger las etiquetas HTML como <p>, <strong> etc y pasarlo sólo como cuerdas...

Imagine que tiene este código en su componente:

const myVal:string ='<strong>Stackoverflow</strong> is <em>helpful!</em>'

Si usas {{myVal}}, obtendrás esto en la vista:

<strong>Stackoverflow</strong> is <em>helpful!</em>

Pero usar [innerHTML]="myVal" hace el resultado como se espera de esta manera:

Stackoverflow es útil!

 1
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-10 12:31:06

Trabajando en AngularJS v2.1.1

<div [innerHTML]="variable or htmlString">
</div>
 0
Author: FACode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-23 07:05:31

La forma de agregar elementos dinámicamente al DOM, como se explica en Angular 2 doc, es usando la clase ViewContainerRef de @Angular/core.

Lo que tiene que hacer es declarar una directiva que implementará ViewContainerRef y actuará como un marcador de posición en su DOM.

Directiva

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appInject]'
})
export class InjectDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Luego, en la plantilla donde desea inyectar el componente:

HTML

<div class="where_you_want_to_inject">    
  <ng-template appInject></ng-template>
</div>

Luego, desde el código del componente inyectado, inyectará el componente contiene el HTML que desea:

import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { InjectDirective } from '../inject.directive';
import { InjectedComponent } from '../injected/injected.component';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

  @ViewChild(InjectDirective) injectComp: InjectDirective;

  constructor(private _componentFactoryResolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
  }

  public addComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
  }

  public removeComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.remove();
  }

}

He añadido una aplicación de demostración totalmente funcional en Angular 2 dinámicamente añadir componente a DOM demo

 0
Author: BogdanC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-29 13:02:15

Si tiene plantillas en su aplicación angular (o cualquier framework), y devuelve plantillas HTML desde su backend a través de una solicitud/respuesta HTTP, está mezclando plantillas entre el frontend y el backend.

¿Por qué no dejar las plantillas en el frontend (yo sugeriría eso), o en el backend (imo bastante intransparente)?

Y si mantiene plantillas en el frontend, ¿por qué no responder con JSON para las solicitudes al backend? No incluso tener que implementar una estructura RESTful, pero mantener las plantillas en un lado hace que su código sea más transparente.

Esto pagará cuando alguien más tenga que lidiar con su código (o incluso usted mismo está volviendo a ingresar su propio código después de un tiempo)!

Si lo haces bien, tendrás componentes pequeños con plantillas pequeñas, y lo mejor de todo, si tu código es imba, ¡alguien que no sepa lenguajes de codificación podrá entender tus plantillas y tu lógica! Así que adicionalmente, mantenga sus funciones / métodos tan pequeños como pueda. Eventualmente descubrirá que mantener, refactorizar, revisar y agregar características será mucho más fácil en comparación con funciones/métodos/clases grandes y mezclar plantillas y lógica entre el frontend y el backend, y mantener la misma lógica en el backend si su frontend necesita ser más flexible (por ejemplo, escribir un frontend de Android o cambiar a un marco de frontend diferente).

Filosofía, hombre:)

P. S.: usted no tienes que implementar código 100% limpio, porque es muy caro, especialmente si tienes que motivar a los miembros del equipo ;) pero: usted debe encontrar un buen equilibrio entre un enfoque de código más limpio y lo que tiene (tal vez ya es bastante limpio)

Revisa el libro si puedes y deja que entre en tu alma: https://de.wikipedia.org/wiki/Clean_Code

 0
Author: Guntram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-30 23:40:47

{[3] {} En[4]}Angular 2 puede hacer 3 tipos de enlaces:

  • [property]="expression" - > Cualquier propiedad html puede enlazar a un
    expresion. En este caso, si la expresión cambia, la propiedad se actualizará, pero esto no funciona al revés.
  • (event)="expression" - > Cuando el evento activa la expresión ejecutar.
  • [(ngModel)]="property" - > Enlaza la propiedad de js (o ts) a html. Cualquier actualización en esta propiedad se notará en todas partes.

Una expresión puede ser un valor, un atributo o un método. Por ejemplo: '4', 'controlador.var', 'getValue()'

Ejemplo aquí

 -1
Author: adrisons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36

El siguiente código le ayudará

Myval se puede reemplazar con el html deseado

<div [innerHTML]="myVal"></div>
 -1
Author: Rahul Cv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 10:16:05

Prueba este código

Su cadena con etiqueta html como abajo

htmlString:string = "Hello<br/>Html"

Puede obtener la cadena en la página html

<ion-content>
<ion-item>
<div [innerHTML] = "'<p>' + htmlString + '</p>'"></div>
</ion-item>
</ion-content>
 -2
Author: Finava Vipul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 12:50:40