在 Angular 中将数据从子级传递给具有 n 个子级的父级,而不会沿途在每个组件中发出
Passing data from children to parent with n children in Angular without emiting in each component along the way
如果我在 Angular 中有这个组件层次结构:
组件 F 中发生了一些 B 应该知道的事情。
我可以做到的一种方法是在 F 中使用 emit()
并将其传递到 A,但这将需要我在 each 组件 E、D 和C,即使他们不关心也不应该关心正在发出的数据 - 所以在 F 中我会写
export class F .... {
...
@Output() emitterName: EventEmitter<any> = new EventEmitter<any>();
doSomething(data) {
...
this.emitterName.emit(data);
}
...
}
那么,class E 应该像 <app-f-selector (emitterName)="setData($event)"><app-f-selector/>
那样调用 F
并且在 E 中,我应该创建一个新函数 setData()
,它只将事件发送到 D:
export class E .... {
...
@Output() emitterName: EventEmitter<any> = new EventEmitter<any>();
setData(data) {
...
this.emitterName.emit(data);
}
...
}
现在我应该对 D 和 C 做同样的事情。
这看起来真的很糟糕,在没有代码重复的情况下,Angular 中是否有一些优雅的方法可以将数据从子组件向上传递到父组件?
类似于 React context?
类似这样的东西(未检查,但作为指南):
export class MySharedService {
private data$ = new Subject<any>();
public setData(data: any) {
this.data$.next(data);
}
public getData(): Observable<any> {
return this.data$.asObservable();
}
}
然后在任何需要此数据的组件中,通过构造函数注入并订阅更改:
this.mySharedService.getData().subscribe(data => ...do something here);
如果您确定您可能只有一个 parent 类型为“A”,您可以在 children 中注入并直接调用它。
export class F {
constructor(
private parentA: AComponent
){}
setData(data) {
this.parentA.doSomething(data);
}
}
但我不推荐这样的结构,因为这会使组件 F 与组件 A 紧密耦合。在我们的项目中,我们仅使用这种方法来实现动态生成的自定义 UI 组件。
您可以使用共享服务来做到这一点。
// shared.service.ts
export class SharedService {
private updateComp = new Subject<any>();
public updateComp$ = this.updateComp.asObservable();
public updateComponent(data: any) {
this.updateComp.next(data);
}
}
// C OR D Component .ts enject sharedService in constructor
ngOnInit() {
this.sharedService.updateComp$.subscribe((res: any) => {
//you code...
});
}
// F Component .ts call share service method i.e.
this.sharedService.updateComponent({ you data});
如果我在 Angular 中有这个组件层次结构:
组件 F 中发生了一些 B 应该知道的事情。
我可以做到的一种方法是在 F 中使用 emit()
并将其传递到 A,但这将需要我在 each 组件 E、D 和C,即使他们不关心也不应该关心正在发出的数据 - 所以在 F 中我会写
export class F .... {
...
@Output() emitterName: EventEmitter<any> = new EventEmitter<any>();
doSomething(data) {
...
this.emitterName.emit(data);
}
...
}
那么,class E 应该像 <app-f-selector (emitterName)="setData($event)"><app-f-selector/>
并且在 E 中,我应该创建一个新函数 setData()
,它只将事件发送到 D:
export class E .... {
...
@Output() emitterName: EventEmitter<any> = new EventEmitter<any>();
setData(data) {
...
this.emitterName.emit(data);
}
...
}
现在我应该对 D 和 C 做同样的事情。 这看起来真的很糟糕,在没有代码重复的情况下,Angular 中是否有一些优雅的方法可以将数据从子组件向上传递到父组件? 类似于 React context?
类似这样的东西(未检查,但作为指南):
export class MySharedService {
private data$ = new Subject<any>();
public setData(data: any) {
this.data$.next(data);
}
public getData(): Observable<any> {
return this.data$.asObservable();
}
}
然后在任何需要此数据的组件中,通过构造函数注入并订阅更改:
this.mySharedService.getData().subscribe(data => ...do something here);
如果您确定您可能只有一个 parent 类型为“A”,您可以在 children 中注入并直接调用它。
export class F {
constructor(
private parentA: AComponent
){}
setData(data) {
this.parentA.doSomething(data);
}
}
但我不推荐这样的结构,因为这会使组件 F 与组件 A 紧密耦合。在我们的项目中,我们仅使用这种方法来实现动态生成的自定义 UI 组件。
您可以使用共享服务来做到这一点。
// shared.service.ts
export class SharedService {
private updateComp = new Subject<any>();
public updateComp$ = this.updateComp.asObservable();
public updateComponent(data: any) {
this.updateComp.next(data);
}
}
// C OR D Component .ts enject sharedService in constructor
ngOnInit() {
this.sharedService.updateComp$.subscribe((res: any) => {
//you code...
});
}
// F Component .ts call share service method i.e.
this.sharedService.updateComponent({ you data});