angular5动态组件parent-chld通信

时间:2018-04-05 08:40:28

标签: angular dynamic angular5 angular-directive

我正在实施the dynamic compoment docs中描述的方法。

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

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

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

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

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

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

1 个答案:

答案 0 :(得分: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