我试图在角度4中的父/子组件之间共享服务数据 . 我有一个工作代码,但我不清楚这是否是最好的选择 . 我正在使用一个可注入的服务类来通过创建Subjects和订阅可观察的方法在parent - > child之间进行通信 . 现在向后传递i:e child - > parent,我通过创建Subjects并订阅parent中的observable来重用同一个服务类 . 这样我订阅了孩子和父母的可观察者,这是正确的方法吗?我在其他地方看到有人建议@Output装饰器在child - > parent之间进行通信,但是我的代码正在使用subscribe机制 . 它会在未来引起任何问题,比如内存泄漏吗?
父组件
constructor(private _textdataservice: TinyEditorService, private _gmapService: GmapService) {
this.subscription = this._gmapService.getMessageC2P().subscribe((message) => {
this.message = message;
this.childCallingParent(message);
});
this.subscription = this._gmapService.getStoreSearchRequest().subscribe((radius) => {
this.radius = radius;
this.retrieveNearByLocations(radius);
});
}
子组件 - >
constructor(private _gmapService: GmapService) {
// subscribe to home component messages
this.mainSubscription = this._gmapService.getMessageP2C().subscribe((addresses) => {
this.mainCoordinates = addresses;
});
this.storeSubscription = this._gmapService.getMessageP2CStore().subscribe((addresses) => {
this.storeCoordinates = addresses;
if(this.storeCoordinates){
for(let coord of this.storeCoordinates){
this.addNearbyStoremarker(coord.name, coord.latitude, coord.longitude);
}
}
});
}
服务 - >
export class GmapService {
private _dataurl='/assets/gmapmarkers.json';
constructor(private _http: Http){}
private parentSubject = new Subject<IGmapData[]>();
private storeSubject = new Subject<IGmapData[]>();
private childSubject = new Subject<String>();
private radiusSubject = new Subject<number>();
sendMessageP2C(latLngArray: IGmapData[]) {
this.parentSubject.next(latLngArray);
}
sendMessageP2CStore(latLngArray: IGmapData[]) {
this.storeSubject.next(latLngArray);
}
sendMessageC2P(message: string) {
this.childSubject.next(message);
}
requestNearByLocations(radius: number) {
this.radiusSubject.next(radius);
}
clearMessage() {
this.parentSubject.next();
this.childSubject.next();
}
getMessageP2C(): Observable<IGmapData[]> {
return this.parentSubject.asObservable();
}
getMessageP2CStore(): Observable<IGmapData[]> {
return this.storeSubject.asObservable();
}
getMessageC2P(): Observable<string> {
return this.childSubject.asObservable();
}
getStoreSearchRequest(): Observable<number> {
return this.radiusSubject.asObservable();
}
getStoreMarkers(): Observable<IGmapData[]> {
return this._http.get(this._dataurl)
.map((response: Response) => <IGmapData[]> response.json());
}
}
3 回答
我想说如果你需要在你的父母和孩子之间来回沟通,最好使用@Input()和@Output() . 原因是当您的组件生效或消失时,Angular会破坏/创建订阅 . 当受试者派上用场时,您需要在没有父/子关系的组件之间广播事件 . 主题使用的一个例子是facebook . 当收到消息时,页面的多个部分将对该事件作出反应而不相互关联 .
但是,如果您实施ngOnDestroy取消订阅您的主题,那么应该保持您的解决方案整洁 . 使用主题方法的风险是最终在您的应用程序中创建了数百个主题,这可能导致性能问题 .
您可以取消ngOnDestroy生命周期钩子中的订阅以防止内存泄漏,如本答案中所述:[how to unsubscribe several subscriber in angular 2
但除非你需要这种额外的复杂性,否则只使用@Output和EventEmitter可能是一个好主意 .
@Input @Output可能很慢,当你从孩子的孩子传递时变得复杂 .
如果您还想在其他组件中使用该数据,则存储方法更好,更灵活 .