Angular 2.0 final: How to instantiate a component from code

后端 未结 4 903
[愿得一人]
[愿得一人] 2021-02-05 16:36

I\'m looking for a way to instantiate a component in Angular2 from within the code of another component. Unlike the many people that have asked a similar question I\'m not so mu

相关标签:
4条回答
  • 2021-02-05 17:01

    There seems to be a (new?) API function for doing what is described in mxii's answer. The ViewContainerRef has the createComponent method. It instantiates the component and adds it to the view.

    let factory = this._cmpFctryRslvr.resolveComponentFactory(AnyComponent);
    let cmp = this.viewContainer.createComponent(factory);
    cmp.instance.name = 'peter';
    
    0 讨论(0)
  • 2021-02-05 17:03

    In case if anyone wants to avoid any statement in accepted answer here is the snippet

        public createComponent<T>(vCref: ViewContainerRef, type: Type<T>): ComponentRef<T> {
    
          let factory = this._cmpFctryRslvr.resolveComponentFactory(type);
    
          // vCref is needed cause of that injector..
          let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector);
    
          // create component without adding it directly to the DOM
          let comp = factory.create(injector);
    
          return comp;
        }
    
    0 讨论(0)
  • 2021-02-05 17:04

    Here's a working demo: https://plnkr.co/edit/pgkgYEwSwft3bLEW95Ta?p=preview

    import {Component, NgModule, ViewChild, ElementRef, Input, Output, EventEmitter, ViewContainerRef, ComponentRef, ComponentFactoryResolver, ReflectiveInjector} from '@angular/core'
    import {BrowserModule} from '@angular/platform-browser'
    
    @Component({
      selector: 'any-comp',
      template: '<div (click)="clicked.emit($event)">here i am.. {{name}}</div>'
    })
    export class AnyComponent {
    
      @Input() name;
      @Output() clicked = new EventEmitter();
    
      constructor() {
        console.log('some1 created me.. ! :)');
      }
    }
    
    @Component({
      selector: 'my-app',
      template: `
        <div>
          <h2>Hello {{name}}</h2>
          <template #placeHolder>
          </template>
        </div>
      `,
    })
    export class App {
    
      @ViewChild('placeHolder', {read: ViewContainerRef}) private _placeHolder: ElementRef;
    
      name:string;
      constructor(private _cmpFctryRslvr: ComponentFactoryResolver) {
        this.name = 'Angular2'
      }
    
      ngOnInit() {
        let cmp = this.createComponent(this._placeHolder, AnyComponent);
    
        // set inputs..
        cmp.instance.name = 'peter';
    
        // set outputs..
        cmp.instance.clicked.subscribe(event => console.log(`clicked: ${event}`));
    
        // all inputs/outputs set? add it to the DOM ..
        this._placeHolder.insert(cmp.hostView);
      }
    
      public createComponent (vCref: ViewContainerRef, type: any): ComponentRef {
    
        let factory = this._cmpFctryRslvr.resolveComponentFactory(type);
    
        // vCref is needed cause of that injector..
        let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector);
    
        // create component without adding it directly to the DOM
        let comp = factory.create(injector);
    
        return comp;
      }
    }
    
    @NgModule({
      imports: [ BrowserModule ],
      declarations: [ App, AnyComponent ], // ! IMPORTANT
      entryComponents: [ AnyComponent ], // ! IMPORTANT --> would be lost due to Treeshaking..
      bootstrap: [ App ]
    })
    export class AppModule {}
    
    0 讨论(0)
  • 2021-02-05 17:09

    You can place your child component inside parent component.

    <parent-component>
      <child-component></child-component>
    </parent-component>
    

    The child component exposes an EventEmitter property with which it emits events when something happens. The parent binds to that event property and reacts to those events. https://angular.io/docs/ts/latest/cookbook/component-communication.html

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