2 equivalentes angulares de ng-bind-html, $ sce.trustAsHTML () y $ compile?

En Angular 1.x, podríamos insertar HTML en tiempo real usando la etiqueta HTML ng-bind-html , combinada con la llamada de JavaScript $sce.trustAsHTML() . Esto nos dio el 80% del camino hasta allí, pero no funcionaría cuando se usen tags angulares, como si insertara HTML que utilizara ng-repeat o directivas personalizadas.

Para que funcione, podríamos usar una directiva personalizada que llame a $ compile .

¿Cuál es el equivalente para todo esto en Angular 2? Podemos enlazar usando [inner-html] pero esto solo funciona para tags HTML muy simples como . No transforma directivas angulares 2 personalizadas en elementos HTML funcionales. (Al igual que Angular 1.x sin el paso $compile .) ¿Cuál es el equivalente de $compile para Angular 2?

En Angular2 debe usar DynamicComponentLoader para insertar algo de “contenido comstackdo” en la página. Entonces, por ejemplo, si quiere comstackr el siguiente html:

 

Common HTML tag

Some angular2 component

luego necesita crear un componente con este html como plantilla (llamémoslo CompiledComponent ) y use DynamicComponentLoader para insertar este componente en la página.

 @Component({ selector: 'compiled-component' }) @View({ directives: [Angular2Component], template: ` 

Common HTML tag

Angular 2 component
` }) class CompiledComponent { } @Component({ selector: 'app' }) @View({ template: `

Before container

After conainer

` }) class App { constructor(loader: DynamicComponentLoader, elementRef: ElementRef) { loader.loadIntoLocation(CompiledComponent, elementRef, 'container'); } }

Mira este plunker

UPD Puede crear componentes dinámicamente justo antes de la llamada loader.loadIntoLocation() :

 // ... annotations class App { constructor(loader: DynamicComponentLoader, elementRef: ElementRef) { // template generation const generatedTemplate = `${Math.random()}`; @Component({ selector: 'compiled-component' }) @View({ template: generatedTemplate }) class CompiledComponent {}; loader.loadIntoLocation(CompiledComponent, elementRef, 'container'); } } 

Personalmente no me gusta, parece un sucio truco para mí. Pero aquí está el plunker

PD. Tenga en cuenta que en este momento angular2 está en desarrollo activo. Entonces la situación se puede cambiar en cualquier momento.

DynamicComponentLoader está en desuso, puede usar ComponentResolver en su lugar

Puede usar esta directiva, agregar tuberías si necesita manipulación adicional de datos. También permite la carga lenta, no la necesita en su caso, pero vale la pena mencionarla.

Directiva (encontré este código e hice algunos cambios, puede hacerlo también para que se ajuste a su gusto o para usarlo tal cual):

 import { Component, Directive, ComponentFactory, ComponentMetadata, ComponentResolver, Input, ReflectiveInjector, ViewContainerRef } from '@angular/core'; declare var $:any; export function createComponentFactory(resolver: ComponentResolver, metadata: ComponentMetadata): Promise> { const cmpClass = class DynamicComponent {}; const decoratedCmp = Component(metadata)(cmpClass); return resolver.resolveComponent(decoratedCmp); } @Directive({ selector: 'dynamic-html-outlet', }) export class DynamicHTMLOutlet { @Input() htmlPath: string; @Input() cssPath: string; constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) { } ngOnChanges() { if (!this.htmlPath) return; $('dynamic-html') && $('dynamic-html').remove(); const metadata = new ComponentMetadata({ selector: 'dynamic-html', templateUrl: this.htmlPath +'.html', styleUrls: [this.cssPath] }); createComponentFactory(this.resolver, metadata) .then(factory => { const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); this.vcRef.createComponent(factory, 0, injector, []); }); } } 

Ejemplo de cómo usarlo:

 import { Component, OnInit } from '@angular/core'; import { DynamicHTMLOutlet } from './../../directives/dynamic-html-outlet/dynamicHtmlOutlet.directive'; @Component({ selector: 'lib-home', templateUrl: './app/content/home/home.component.html', directives: [DynamicHTMLOutlet] }) export class HomeComponent implements OnInit{ html: string; css: string; constructor() {} ngOnInit(){ this.html = './app/content/home/home.someTemplate.html'; this.css = './app/content/home/home.component.css'; } } 

home.component.html:

  

Después de leer mucho y de estar cerca de abrir un tema nuevo, decidí responder aquí solo para tratar de ayudar a los demás. Como he visto, hay varios cambios con la última versión de Angular 2. (Actualmente Beta9)

Intentaré compartir mi código para evitar la misma frustración que tuve …

Primero, en nuestro index.html

Como de costumbre, deberíamos tener algo como esto:

  ****  Loading...   

AppComponent (usando innerHTML)

Con esta propiedad podrá renderizar el HTML básico, pero no podrá hacer algo similar a Angular 1.x como $ comstackr a través de un scope:

 import {Component} from 'angular2/core'; @Component({ selector: 'my-app', template: ` 

Hello my Interpolated: {{title}}!

`, }) export class AppComponent { public title = 'Angular 2 app'; public htmlExample = '
' + '' + 'Hello my Interpolated: {{title}}' + '
' }

Esto representará lo siguiente:

¡Hola, mi aplicación Interpolated: Angular 2!

Hola mi propiedad vinculada: aplicación angular 2!

Hola, mi interpolación: {{título}}

AppComponent que usa DynamicComponentLoader

Hay un pequeño error con los documentos, documentado aquí . Entonces, si tenemos en cuenta eso, mi código debería verse ahora así:

 import {DynamicComponentLoader, Injector, Component, ElementRef, OnInit} from "angular2/core"; @Component({ selector: 'child-component', template: ` 

Hello my Interpolated: {{title}}

` }) class ChildComponent { title = 'ChildComponent title'; } @Component({ selector: 'my-app', template: `

Hello my Interpolated: {{title}}!

End of parent: {{endTitle}}

`, }) export class AppComponent implements OnInit{ public title = 'Angular 2 app'; public endTitle= 'Bye bye!'; constructor(private dynamicComponentLoader:DynamicComponentLoader, private elementRef: ElementRef) { // dynamicComponentLoader.loadIntoLocation(ChildComponent, elementRef, 'child'); } ngOnInit():any { this.dynamicComponentLoader.loadIntoLocation(ChildComponent, this.elementRef, 'child'); } }

Esto representará lo siguiente:

¡Hola, mi aplicación Interpolated: Angular 2!

Hola mi propiedad vinculada: aplicación angular 2!

Hola, mi propiedad vinculada: título de ChildComponent

Hola, mi título Interpolated: ChildComponent

Fin de los padres: adiós!

Creo que todo lo que tienes que hacer es establecer el elemento que quieres que tenga comstackdo html con el [innerHTML] = “yourcomponentscopevar”

Angular proporcionó la clase DynamicComponentLoader para cargar html dinámicamente. DynamicComponentLoader tiene métodos para insertar componentes. loadIntoLocation es uno de ellos para insertar componentes.

paper.component.ts

 import {Component,DynamicComponentLoader,ElementRef,Inject,OnInit} from 'angular2/core'; import { BulletinComponent } from './bulletin.component'; @Component({ selector: 'paper', templateUrl: 'app/views/paper.html' } }) export class PaperComponent { constructor(private dynamicComponentLoader:DynamicComponentLoader, private elementRef: ElementRef) { } ngOnInit(){ this.dynamicComponentLoader.loadIntoLocation(BulletinComponent, this.elementRef,'child'); } } 

bulletin.component.ts

 import {Component} from 'angular2/core'; @Component({ selector: 'bulletin', templateUrl: 'app/views/bulletin.html' } }) export class BulletinComponent {} 

paper.html

 

Pocas cosas que debes cuidar:

  • No llame a loadIntoLocation dentro del constructor de clase. La vista de componentes aún no se crea cuando se llama al constructor del componente. Obtendrás un error –

Error durante la instanciación de AppComponent !. No hay ninguna directiva de componente en el elemento [object Object]

  • Coloque anchorName #child en html; de lo contrario, obtendrá un error.

No se pudo encontrar el niño variable

Eche un vistazo a este módulo https://www.npmjs.com/package/ngx-dynamic-template

Después de una larga investigación, solo esto me ayudó. El rest de las soluciones parece estar desactualizado.