Angular: How to pass data in ngComponentOutlet through Injector

前端 未结 3 801
清酒与你
清酒与你 2021-01-20 10:02

I\'m trying to dynamically create and show component and i need to pass some data into it, so that it knows what to show.

Here is my code:

html part:

相关标签:
3条回答
  • 2021-01-20 10:45

    Hey there change widgets to widgets = [], otherwise angular will keep calling the method in the ngFor loop. If you console log in the constructor for the component you find this is happening.

    0 讨论(0)
  • 2021-01-20 10:48

    If you open code of NgComponentOutlet directive:

    @Directive({selector: '[ngComponentOutlet]'})
    export class NgComponentOutlet implements OnChanges, OnDestroy {
      @Input() ngComponentOutlet: Type<any>;
      @Input() ngComponentOutletInjector: Injector;
    

    you can notice that it takes ngComponentOutlet input that should have type Type<any> but you're passing object to it.

    Also we can see that this directive can take Injector as @Input. So lets leverage this knowledge to do your task.

    For example we wrote template like:

    <ng-container *ngComponentOutlet="component; injector: injector"></ng-container>
    

    Now lets declare component and injector properties in component class:

    @Component({...})
    export class AppComponent  {
    
      component: Type<any>;
      injector: Injector;
    
      constructor(private inj: Injector) {}
    
      ngOnInit() {
        this.component = ProjectComponent; // note: we're passing type here
        this.injector = Injector.create([
          { provide: BasicProject, useValue: new Project('test name') }
        ], this.inj);
      }
    }
    

    and your ProjectComponent now uses angular DI mechanism to get data we passed to injector:

    export class ProjectComponent {
      name: string;
    
      constructor(project: BasicProject) {
        this.name = project.name;
      }
    }
    

    Stackblitz Example

    0 讨论(0)
  • 2021-01-20 11:04

    Thanks to yuzui's comment I managed to get something working

    The full runnable code can be found on Stackblitz

    export class AppComponent  {
      name = 'Dynamic components in Angular 5';
      private injectors = {};
    
      constructor(private inj: Injector) {
      }
    
      get widgets() {
        return [
          {id: 1, widgetType:'child-component', settings: { showSecondLine: false} },
          {id: 2, widgetType:'child2-component', settings: { text: 'helloooooooooo'} },
          ];
      }
      
      getComponent(config: WidgetConfiguration) {
        switch (config.widgetType) {
          case 'child-component':
            return ChildComponent;
          case 'child2-component':
            return Child2Component;
        }
      }
    
       getInjector(config: WidgetConfiguration) {
        let inject = this.injectors[config.id];
        if (!inject) {
          inject = Injector.create([
            { provide: GeneralSettings, useValue: config.settings }
          ], this.inj);
          this.injectors[config.id] = inject;
        }
    
        return inject;
      }
    }

    0 讨论(0)
提交回复
热议问题