Angular 角度4组件通信-与订阅者的子级到父级

Angular 角度4组件通信-与订阅者的子级到父级,angular,parent-child,angular2-observables,Angular,Parent Child,Angular2 Observables,我正在尝试在angular 4中的父/子组件之间共享服务数据。我有一个工作代码,但我不清楚这是否是最好的选择。我正在使用一个可注入服务类,通过创建主题和订阅可观察的方法,在父-->子对象之间进行通信。现在,为了向后通信i:e child-->parent,我通过在parent中创建subject和订阅observable来重新使用相同的服务类。这样的话,我在孩子和父母身上都可以观察到,这是正确的方法吗?我在其他地方看到,有人建议@Output decorator在子-->父级之间进行通信,但我的

我正在尝试在angular 4中的父/子组件之间共享服务数据。我有一个工作代码,但我不清楚这是否是最好的选择。我正在使用一个可注入服务类,通过创建主题和订阅可观察的方法,在父-->子对象之间进行通信。现在,为了向后通信i:e child-->parent,我通过在parent中创建subject和订阅observable来重新使用相同的服务类。这样的话,我在孩子和父母身上都可以观察到,这是正确的方法吗?我在其他地方看到,有人建议@Output decorator在子-->父级之间进行通信,但我的代码使用的是订阅机制。将来会不会出现内存泄漏之类的问题

父组件

  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);
});
}

子组件-->

}

服务-->

导出类GmapService{
private _dataurl='/assets/gmapmarkers.json';
构造函数(私有http:http){}
private parentSubject=新主题();
private storeSubject=新主题();
private childSubject=新主题();
private radiusSubject=新主题();
sendMessageP2C(latLngArray:IGmapData[]{
这个.parentSubject.next(latLngArray);
}
sendMessageP2CStore(latLngArray:IGmapData[]){
this.storeSubject.next(latLngArray);
}
sendMessageC2P(消息:字符串){
this.childSubject.next(消息);
}
requestNearByLocations(半径:编号){
this.radiusubject.next(radius);
}
clearMessage(){
this.parentSubject.next();
this.childSubject.next();
}
getMessageP2C():可观察{
返回此.parentSubject.asObservable();
}
getMessageP2CStore():可观察{
返回此.storeSubject.asObservable();
}
getMessageC2P():可观察{
返回此.childSubject.asObservable();
}
getStoreSearchRequest():可观察{
返回此.radiusubject.asObservable();
}
getStoreMarkers():可观察{
返回此。_http.get(此。_数据URL)
.map((response:response)=>response.json());
}

}
您可以取消Ngondestry lifecycle挂钩中的订阅,以防止内存泄漏,如以下回答所述:[


但是,除非您需要这种额外的复杂性,否则仅使用@Output和EventEmitter可能是一个好主意。

如果您需要在父级和子级之间来回通信,最好使用@Input()和@Output()。 原因是Angular将在组件恢复使用或消失时为您销毁/创建订阅。 当您需要跨没有父/子关系的组件广播事件时,主题就派上了用场。 主题使用的一个例子是facebook。当收到一条消息时,页面的多个部分会对该事件做出反应,而彼此之间没有关联

然而,如果您实施Ngondestry以取消您的主题的订阅,则应保持您的解决方案整洁。
使用主题方法的风险在于,最终会在你的应用程序中创建数百个主题,这可能会导致性能问题。

@Input@Output可能会很慢,当你从一个孩子的孩子那里经过时会变得复杂


如果您希望在其他组件中也使用该数据,则存储方法更好、更灵活。

谢谢您的回复。.我已经在父级和子级中使用了Ngondestory。我也同意这样一个事实,即父级和子级之间的双向发布不是一个好主意,因为我没有在网上找到任何实现。我可以使用@output decorator,但希望将代码保留在服务类中的一个位置。我应该在child中使用输出装饰器吗?@output属性将位于子组件中,但只有在您直接在子组件和父组件之间传递数据,而不是通过某个外部服务时,@output属性才会出现。所谓存储,您指的是服务方法@vineet?
  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);
    }
  }
});