简体   繁体   中英

Pass data to dynamically created angular modules and components

I need to pass data to a dynamically created angular module like an id or JSON my controller code is like this.

Logic Explained - The API provides the layout of the page if primary module comes first or secondary module (There are more which cannot be handled by an ngif) all modules have different designs primary and secondary have n no of styles which are also decided by the API too. The id is the key to decide all the designs of that page

export class MainLayoutComponent implements OnInit {

 modules: any = [
  {
    module: PrimaryModule,
    component: PrimaryLandingPageComponent,
    id: 1
  },
  {
    module: SecondaryModule,
    component: SecondaryLandingPageComponent,
    id: 2
  },
 ];

 constructor(public compiler: Compiler) {  }

 returnCompiledModule(moduleItem) {
   return this.compiler.compileModuleSync(moduleItem);
 }

 ngOnInit() {
   console.log('hello');
 }

}

why I am doing like this is because I have the layout of the page which is decided by the API and each module has different types of components with different designs (That code has been omitted) This is how I am rendering in HTML

<ng-container *ngFor="let module of modules">
  <ng-container 
    *ngComponentOutlet="module.component; 
    ngModuleFactory: returnCompiledModule(module.module);">
  </ng-container>
</ng-container>

Is there any way I can pass data to the module or the component corresponding to it the id values in the JSON or the JSON itself via the router, another syntactical sweetener I may be missing, services or the compiler itself I have been stuck here for some time any help would be appreciated or is there any other way to do this is in angular version 8 without IVY Thanks in advance.

In order to pass data to dynamically created components using ngComponentOutlet , you can use Injector .

Just add this function to your MainLayoutComponent :

getInjector(moduleItem) {
  return Injector.create([
    { provide: Number, useValue: moduleItem.id }
  ], this.injector);
}

and change its constructor to inject Injector object:

constructor(public compiler: Compiler, private injector: Injector) {  }

Then - as you can see in the docs - inside ngComponentOutlet you can pass the data by specifying the injector like this:

<ng-container *ngFor="let module of modules">
  <ng-container 
    *ngComponentOutlet="module.component; 
                        ngModuleFactory: returnCompiledModule(module.module);
                        injector: getInjector(module);">
  </ng-container>
</ng-container>

Now each of your Component classes which can be dynamically created ( PrimaryLandingPageComponent , SecondaryLandingPageComponent etc.) should contain id argument in its constructor which you can further use as needed:

constructor(id: Number) { 
  // do whatever you need with id value
}

I haven't tested this code so you would probably need to fix some issues, but hopefully you get the idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM