2 votes

Chargement dynamique de composants Angular 4 à l'aide d'un schéma json

Je suis en train de créer un petit poc pour essayer de savoir s'il est possible de charger des composants en fonction d'une structure de données json donnée. json fournira un tableau de sélecteurs de composants. J'ai essayé un petit exemple selon les matériaux de référence que j'ai trouvé en ligne. J'ai utilisé le "componentFactoryResolver" qui est recommandé par Angular.

J'ai créé deux composants et je les ai enregistrés dans mon module avec le décorateur entrycomponent comme suit

entryComponents: [PersonalDetailsComponent, ContactDetailsComponent],

et dans mon composant d'application j'utilise le code suivant

  @ViewChild('dynamicInsert', { read: ViewContainerRef }) dynamicInsert: ViewContainerRef;
  constructor(private componentFactoryResolver: ComponentFactoryResolver) {
  }
  ngAfterViewInit() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(PersonalDetailsComponent );
    const componentFactory2 = this.componentFactoryResolver.resolveComponentFactory(ContactDetailsComponent);
    this.dynamicInsert.clear();
    this.dynamicInsert.createComponent(componentFactory);
    this.dynamicInsert.createComponent(componentFactory2);
  }

et comme vous le voyez, je dois créer un composant pour chaque composant que j'utilise. mais avoir ceci à l'intérieur d'une boucle pourrait ne pas être la meilleure façon de le faire. j'apprécierais beaucoup si quelqu'un pouvait me donner quelques conseils pour le faire d'une manière appropriée. mon json actuel ressemblerait à quelque chose comme ceci

{
         "step":"1",
         "viewed":false,
         "stepDependant":{
            "parentComponent":null,
            "childComponent":null,
            "varMap":null
         },
         "widgets":[
            {
               "Component":"shipper",
               "inputs":[
                  {
                     "ServiceLine":"Export"
                  }
               ],
               "outputs":[

               ],
               "name":"Shipper Details"
            },
            {
               "Component":"shipper",
               "inputs":[
                  {
                     "ServiceLine":"Export"
                  }
               ],
               "outputs":[

               ],
               "name":"Consignee Details"
            },
            {
               "Component":"status-of-shipment",
               "inputs":[

               ],
               "outputs":[

               ],
               "name":"Status of Shipment"
            }
         ]
      }

j'apprécie beaucoup vos contributions

2voto

AlesD Points 3284

Comme vous l'avez déjà constaté, le componentFactoryResolver est le moyen correct de créer des composants dynamiquement à partir du code. Avec cette approche, ce que je ferais dans votre cas, c'est de créer une carte ou un service qui associe les sélecteurs de composants aux types de composants. De cette façon, vous pouvez consulter rapidement le type lorsque vous créez les composants dynamiques à partir des données JSON. À partir des types, vous résolvez ensuite la fabrique et ajoutez les composants comme dans votre exemple.

Si vous disposez d'un ensemble prédéfini de composants connus, une autre solution serait de les définir tous en tant que <ng-template> dans le composant parent comme ceci :

<ng-template #shipper><shipper ></shipper></ng-template>
<ng-template #statusOfShippment><status-of-shipment ></status-of-shipment></ng-template>

Vous pouvez ensuite obtenir les modèles dans le composant en utilisant le décorateur @ViewChild.

@ViewChild('shipper')
shipperTemplate: TemplateRef<any>;
@ViewChild('statusOfShippment')
statusOfShippmentTemplate: TemplateRef<any>;

Vous pouvez ensuite créer les composants de la même manière qu'avec l'usine.

this.dynamicInsert.createEmbeddedView(shipper);
this.dynamicInsert.createEmbeddedView(statusOfShippment);

Ce qui est bien dans cette approche, c'est que vous pouvez toujours avoir une liaison classique entre les modèles et envoyer un objet de contexte différent à chaque modèle.

<ng-template #shipper><shipper [ServiceLine]="ServiceLine"></shipper></ng-template>

this.dynamicInsert.createEmbeddedView(shipper, {ServiceLine:"Export"});

De cette façon, vous pourriez envoyer directement un objet créé à partir de votre JSON et configurer les liaisons entre les composants. Si vous utilisez la fabrique de composants, vous devez tout configurer manuellement à partir du code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X