首页 文章

angular5动态组件parent-chld通信

提问于
浏览
1

我正在实现the dynamic compoment docs中描述的方法 .

我需要我的动态组件能够向父组件发出事件,并且作为响应,父组件可能需要调用子组件的方法 .

我知道当子组件在父模板中时,如何将子事件绑定到父方法:

孩子

  • @Output() xevent : eventEmitter<string>;
    父模板中的
  • <child-comp (xevent)="aParentMethod($event)"

但是,在动态组件方法中,父模板包含一个指令,该指令又将包装动态实例化的组件 .

如何在动态组件上设置@Input和@Output属性,并将它们从父级传播到子级,反之亦然?

此外,如何让父母调用孩子的方法?

1 回答

  • 1

    就动态组件而言,角度文档有点过时了 . 看看Angular 4中引入的 [ngComponentOutlet] 指令 . 它可能会大大简化您的组件 .

    简单的用例如下:

    import { Component } from '@angular/core';
    import { HelloComponent } from './hello.component';
    
    @Component({
      selector: 'my-app',
      template: `
        <ng-container [ngComponentOutlet]="component"></ng-container>
      `,
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      // [ngTemplateOutlet] binds to this property, you can set this dynamically!
      component = HelloComponent; 
    }
    

    有关api documentation中NgComponentOutlet的更多信息 .

    所以这是一个好消息 . 坏消息是目前无法访问以这种方式创建的组件的 @Inputs@Outputs . 你可以在github上跟踪这个issue .

    同时,有人建议使用ng-dynamic-component .

    您还可以使用共享服务实现父/子通信:

    app.component.ts

    import { Component } from '@angular/core';
    import {CommunicationService} from './communication.service';
    import {HelloComponent} from './hello.component';
    
    @Component({
      selector: 'my-app',
      template: `
      <input (keydown.enter)="send(input.value); input.value = ''" #input />
      <ng-container [ngComponentOutlet]="component"></ng-container>
      `,
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      component = HelloComponent;
    
      constructor(private communicationService: CommunicationService) {}
    
      send(val: string) {
        this.communicationService.next(val);
      }
    }
    

    communication.service.ts

    import {Injectable } from '@angular/core';
    import {Subject} from 'rxjs/Subject';
    import  {Observable } from 'rxjs/Observable';
    
    @Injectable()
    export class CommunicationService {
      private messageSource = new Subject();
      message$ = this.messageSource.asObservable();
    
      next(val: string) {
        this.messageSource.next(val);
      }
    }
    

    hello.component.ts

    import { Component, Input } from '@angular/core';
    import {Observable} from 'rxjs/Observable';
    import {CommunicationService} from './communication.service';
    
    @Component({
      selector: 'hello',
      template: `<h1>{{ message$ | async }} </h1>`,
      styles: [`h1 { font-family: Lato; }`]
    })
    export class HelloComponent  {
      message$: Observable<string>;
    
      constructor(private communication: CommunicationService) {
        this.message$ = communication.message$;
      }
    }
    

    Live demo

相关问题