首页 文章

Angular 4组件通信 - 具有订户的子到父

提问于
浏览
1

我试图在角度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 回答

  • 1

    我想说如果你需要在你的父母和孩子之间来回沟通,最好使用@Input()和@Output() . 原因是当您的组件生效或消失时,Angular会破坏/创建订阅 . 当受试者派上用场时,您需要在没有父/子关系的组件之间广播事件 . 主题使用的一个例子是facebook . 当收到消息时,页面的多个部分将对该事件作出反应而不相互关联 .

    但是,如果您实施ngOnDestroy取消订阅您的主题,那么应该保持您的解决方案整洁 . 使用主题方法的风险是最终在您的应用程序中创建了数百个主题,这可能导致性能问题 .

  • 3

    您可以取消ngOnDestroy生命周期钩子中的订阅以防止内存泄漏,如本答案中所述:[how to unsubscribe several subscriber in angular 2

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

  • 1

    @Input @Output可能很慢,当你从孩子的孩子传递时变得复杂 .

    如果您还想在其他组件中使用该数据,则存储方法更好,更灵活 .

相关问题