page link change angular angular2-template angular2-databinding

link - Enlace HTML angular



router events subscribe angular 4 (18)

En Angular 2 puedes hacer 3 tipos de enlaces:

  • [property]="expression" -> Cualquier propiedad html puede vincularse a un
    expresión. En este caso, si la expresión cambia, la propiedad se actualizará, pero esto no funciona de otra manera.
  • (event)="expression" -> Cuando el evento se activa, ejecuta la expresión.
  • [(ngModel)]="property" -> Vincula la propiedad de js (o ts) a html. Cualquier actualización de esta propiedad se notará en todas partes.

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

Ejemplo here

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

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

Necesito de alguna manera vincular el innerHTML de un div al valor de la variable.


En [email protected]:

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

inválido

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

-> arroja un error (Interpolación en lugar de Expresión esperada)

correcto

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

-> esta es la forma correcta.

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

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

insinuación

El 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 por motivos de seguridad.
Tales 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 Componente dinámico con Angular 2.0?



La forma de agregar elementos dinámicamente a DOM, como se explica en el documento de Angular 2, es mediante el uso de la clase ViewContainerRef de @ Angular / core.

Lo que debe 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 que 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(); } }

Agregué una aplicación de demostración completamente funcional en Angular 2 para agregar componentes dinámicamente a la demostración DOM



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

Creo que es mejor devolver datos sin procesar de la aplicación del lado del servidor y vincularlos a una plantilla en el lado del cliente. Esto genera solicitudes más ágiles, ya que solo está devolviendo json desde su servidor.

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

Sé que Angular 1.x tiene un enlace html, pero aún 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.

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


Puede aplicar varias canalizaciones para estilo, enlace y HTML como se indica en .html

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

y en la tubería .ts para el desinfectante ''URL''

import { Component, Pipe, PipeTransform } from ''@angular/core''; import { DomSanitizer } from ''@angular/platform-browser''; @Pipe({ name: ''safeUrl'' }) export class SafeUrlPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url) { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } }

tubería para desinfectante ''HTML''

import { Component, Pipe, PipeTransform } from ''@angular/core''; import { DomSanitizer } from ''@angular/platform-browser''; @Pipe({ name: ''safeHtml'' }) export class SafeHtmlPipe implements PipeTransform { constructor(private sanitized: DomSanitizer) {} transform(value) { return this.sanitized.bypassSecurityTrustHtml(value); } }

esto se aplicará sin perturbar ningún estilo y evento de clic de enlace


Puede usar varios enfoques para lograr la solución. Como ya se dijo en la respuesta aprobada, puede usar:

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

dependiendo de lo que intente lograr, también puede probar otras cosas como DOM de javascript (no recomendado, las operaciones DOM son lentas):

Presentación

<div id="test"></test>

Componente

var p = document.getElementsById("test"); p.outerHTML = myVal;

Enlace de propiedad

Javascript DOM HTML externo


Puedes usar este método

<div [innerHTML]=var></div>

o vincularlo por id

<div #html></div>

y en el componente

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; } }


Si desea eso en Angular 2 o Angular 4 y también desea mantener CSS en línea, puede usar

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


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

¿Por qué no dejar las plantillas en la interfaz (sugeriría eso) o en el servidor (bastante intransparente)?

Y si mantiene las plantillas en la interfaz, ¿por qué no solo responde con JSON para las solicitudes al backend? Ni siquiera tiene que implementar una estructura RESTful, pero mantener las plantillas a un lado hace que su código sea más transparente.

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

Si lo hace bien, tendrá componentes pequeños con plantillas pequeñas, y lo mejor de todo, si su código es imba, ¡alguien que no conozca los lenguajes de codificación podrá comprender sus plantillas y su lógica! Además, mantenga sus funciones / métodos lo más pequeños que 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 back-end, y mantener la mayor parte de la lógica en el back-end. si su interfaz necesita ser más flexible (por ejemplo, escribir una interfaz de Android o cambiar a un marco de interfaz diferente).

Filosofía, hombre :)

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

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


Siempre podemos pasar contenido html a la propiedad innerHTML para representar contenido dinámico html, pero ese contenido dinámico html también puede infectarse o maliciarse. Entonces, antes de pasar contenido dinámico a innerHTML , siempre debemos asegurarnos de que el contenido esté desinfectado (usando DOMSanitizer ) para que podamos escapar de todo el contenido malicioso.

Prueba debajo de la tubería:

import { Pipe, PipeTransform } from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; @Pipe({name: ''safeHtml''}) export class SafeHtmlPipe implements PipeTransform { constructor(private sanitized: DomSanitizer) { } transform(value: string) { return this.sanitized.bypassSecurityTrustHtml(value); } } Usage: <div [innerHTML]="content | safeHtml"></div>


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

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

¿Alguna vez ha tenido propiedades en su componente que contienen algunas marcas html o entidades que necesita mostrar en su plantilla? La interpolación tradicional no funcionará, pero el enlace de propiedad innerHTML viene al rescate.

¡Usar {{myVal}} NO funciona como se esperaba! Esto no recogerá las etiquetas HTML como <p> , <strong> etc. y lo pasará solo como cadenas ...

Imagine que tiene este código en su componente:

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

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

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

pero el uso de [innerHTML]="myVal" produce el resultado como se esperaba de esta manera:

¡ es útil!


Solo para obtener una respuesta completa, si su contenido html está en una variable componente, también puede usar:

<div [innerHTML]=componementVariableThatHasTheHtml></div>


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); } } }

Para ser utilizado

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


[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 necesitas hacer es crear un div en tu archivo html y darle alguna identificación:

<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 texto al elemento html.

Es solo una forma de hacerlo usando JavaScript nativo, pero en un 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 .com/questions/36265026/…


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 confiable usando Angulars DOM sanitizer para que no elimine partes potencialmente inseguras del contenido

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

con una pipa 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 } }

Consulte también En RC.1, algunos estilos no se pueden agregar utilizando la sintaxis de enlace

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

Advertencia de seguridad

Confiar en el HTML agregado por el usuario puede representar un riesgo de seguridad. Los documentos mencionados anteriormente indican:

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

Marcado angular

Algo 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 angular en 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 contiene marcado específico angular (propiedad o enlace de valor, componentes, directivas, tuberías, ...) 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 plantillas dinámicas para compilar componentes dinámicos con Angular 2.0?


Trabajando en AngularJS v2.1.1

<div [innerHTML]="variable or htmlString"> </div>