我正在实施the dynamic compoment docs中描述的方法。
我需要动态组件才能向父组件发出事件,作为响应,父组件可能需要调用子组件的方法。
我知道当子组件在父模板中时,如何将子事件绑定到父方法:
@Output() xevent : eventEmitter<string>;
<child-comp (xevent)="aParentMethod($event)"
但是在动态组件方法中,父模板包含一个指令,该指令又将包装动态实例化的组件。
如何在动态组件上设置@Input和@Output属性,并将它们从父级传播到子级,反之亦然?
此外,如何让父母为孩子调用方法?
答案 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$;
}
}