角度动态组件 parent-chld 通讯
angular5 dynamic compoments parent-chld communication
我正在实施 the dynamic compoment docs 中描述的方法。
我需要我的动态组件能够向 parent 组件发出事件,作为响应,parent 组件可能需要调用 child 组件的方法。
当 child 组件位于 parent 的模板中时,我知道如何将 child 事件绑定到 parent 的方法:
@Output() xevent : eventEmitter<string>;
在 child
<child-comp (xevent)="aParentMethod($event)"
parent 模板
但是在动态组件方法中,parent 模板包含一个指令,该指令反过来将包装动态实例化的组件。
如何在动态组件上设置@Input 和@Output 属性并将它们从parent 传播到child 和vice-versa?
此外,我怎样才能让 parent 调用 child 上的方法?
就动态组件而言,angular 文档有点过时了。看一下 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;
}
中有关 NgComponentOutlet 的更多信息
所以这是个好消息。坏消息是目前无法访问以这种方式创建的组件的 @Inputs
和 @Outputs
。您可以在 github.
上跟踪此 issue
同时,有人建议使用 ng-dynamic-component。
您还可以使用共享服务实现 parent/child 通信:
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$;
}
}
我正在实施 the dynamic compoment docs 中描述的方法。
我需要我的动态组件能够向 parent 组件发出事件,作为响应,parent 组件可能需要调用 child 组件的方法。
当 child 组件位于 parent 的模板中时,我知道如何将 child 事件绑定到 parent 的方法:
@Output() xevent : eventEmitter<string>;
在 child<child-comp (xevent)="aParentMethod($event)"
parent 模板
但是在动态组件方法中,parent 模板包含一个指令,该指令反过来将包装动态实例化的组件。
如何在动态组件上设置@Input 和@Output 属性并将它们从parent 传播到child 和vice-versa?
此外,我怎样才能让 parent 调用 child 上的方法?
就动态组件而言,angular 文档有点过时了。看一下 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;
}
中有关 NgComponentOutlet 的更多信息
所以这是个好消息。坏消息是目前无法访问以这种方式创建的组件的 @Inputs
和 @Outputs
。您可以在 github.
同时,有人建议使用 ng-dynamic-component。
您还可以使用共享服务实现 parent/child 通信:
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$;
}
}