web-dev-qa-db-fra.com

Comment rendre un modèle dynamique avec des composants dans Angular2

J'ai essayé de nombreuses options de stackoverflow comme Charger dynamiquement les composants existants Angular 2 Final Release .

Ce que je veux faire, c'est obtenir une page html avec une demande ajax et rendre/compiler ce modèle dans mon composant personnalisé.

J'ai compris que angular2 a deux composants obsolètes et que je dois utiliser ComponentFactoryResolver .

Dans mon ancienne solution, je pouvais simplement définir un "[innerHtml]" pour rendre le HTML. Maintenant, j'ai besoin d'une nouvelle solution.

Qui peut m'aider?

page.component.ts

import { Component, ViewChild, ViewContainerRef, ComponentFactory, OnInit, ComponentFactoryResolver } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';


@Component({
    selector: "wd-page",
    templateUrl: "/app/page/page.component.html",
    providers: []
})
export class PageComponent implements OnInit {

    // we need the viewcontainer ref, so explicitly define that, or we'll get back
    // an element ref.
    @ViewChild('dynamicChild', { read: ViewContainerRef })
    private target: ViewContainerRef;

    private page = {
        Source: "<div><h2>Hello world</h2><one-of-my-components></one-of-my-components></div>"
    }


    constructor(
        private vcRef: ViewContainerRef,
        private resolver: ComponentFactoryResolver) { }


        ngOnInit() {
            //What code do i need here?
        }
}
<div #dynamicChild></div>

<!-- Old implementation!

    <div *ngIf="!showSource" [innerHTML]="page">
    </div>
-->
11
Linksonder

Problème résolu Merci à Yurzui,

https://plnkr.co/edit/TAbupH4si62x10QZ7xuc?p=preview

La sortie HTML générique d'un autre post ( Angular 2.1.0 crée un composant enfant à la volée, dynamiquement ) peut être utilisée pour rendre des modèles avec des directives personnalisées.

N'oubliez pas d'importer un module avec tous les composants personnalisés que vous souhaitez rendre!

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
const cmpClass = class DynamicComponent {};
const decoratedCmp = Component(metadata)(cmpClass);

// Import the module with required components here
@NgModule({ imports: [CommonModule, RouterModule, SharedModule], declarations: [decoratedCmp] })
class DynamicHtmlModule { }

return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
   .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
    return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
  });
}
9
Linksonder

J'ai fait de minuscules changements pour utiliser mes propres composants (comme HomeComponent) chez @Yurzui et les solutions de @Linksonder. https://plnkr.co/edit/27x0eg?p=preview

Il s'agit essentiellement d'ajouter AppModule à DynamicHtmlModule en tant qu'importation supplémentaire à l'intérieur de createComponentFactory ().

@NgModule({ imports: [AppModule, CommonModule, RouterModule, SharedModule], declarations: [decoratedCmp] })
class DynamicHtmlModule { }

Et exporte nos propres composants sur AppModule

@NgModule({
  ...
  exports: [HomeComponent, AboutComponent],
  ...
})
export class AppModule { }
1
Ryang MinHo