首页 > 解决方案 > 我想发送一个可观察的 2 个父组件。我该怎么做?我需要使用 EventEmitter 吗?

问题描述

我有一个页面组件、一个列表组件和一个详细信息组件(父到子层次结构:页面->列表->详细信息),并且我试图通过组件共享在详细信息组件中获取一个可观察到的页面组件。

我已经尝试通过将 observable 放入 EventEmitter 并将其向上发送来做到这一点,但是,它似乎不起作用。它可能是以下两种情况之一:我错误地发送了 observable,或者我正确地发送了 observable,但我错误地从 EventEmitter 中提取了它。代码看起来像这样。

细节组件:

@Output() outputHumidityWarning$ = new EventEmitter<Observable<boolean>>();
...
ngOnInit() {
  this.outputHumidityWarning$.emit(this.humidityWarning$);
}

其中湿度警告 $ 是 Observable 类型

列表组件模板:

<app-detail (outputHumidityWarning$)="inputHumidityWarning($event)"</app-detail>

列表组件:

private humidityWarning = new Replaysubject<boolean>(1);
...
ngOnInit() {
  this.humiditywarning.subscribe(all => console.log(all));
}
...
inputHumidityWarning = function (humidityWarning) {
  this.humidityWarning = humidityWarning;
}

我也试过:

inputHumidityWarning = function (humidityWarning) {
  this.humidityWarning.next(humidityWarning);
}
...
inputHumidityWarning = function (humidityWarning) {
  this.humidityWarning.next(of(humidityWarning));
}

没有错误,但我不会在控制台上得到任何东西。当我在设置后 console.log this.humidityWarning 时,我会得到一个 AnonymousSubject。这就是为什么我尝试将其包装为 of()。当我 console.log(humanityWarning) 我会得到一个 EventEmitter

标签: angularangular2-observableseventemitter

解决方案


我可能误解了您的目标,但我以不同的方式完成了类似的组件通信。例如,考虑可能需要在多个组件之间共享的应用程序状态。

我通常创建一个服务,该服务公开一个可观察对象并将行为主体实现为观察者和可观察对象。然后我可以将服务注入到像你的子组件这样的组件中作为输入,并在其他需要观察的组件中订阅服务,比如你的父组件。我通常使用接口在服务中定义具有已定义类型的 observable 来保留它。

这是我创建的一个示例,用于管理由各种组件更新的搜索参数。

服务:

import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { SearchParams, Filter } from '../components/searchParam/searchparams.entity';
import { ISearchParams } from '../components/searchParam/searchparams.interface';
import { parkDetails } from '../services/getParkDetails.service';


@Injectable()
export class searchParamStateService {
    private _searchParamSource: BehaviorSubject<ISearchParams>;
    searchParams: Observable<ISearchParams>;
    private dataStore: ISearchParams;

    constructor() {    
        this.dataStore = new SearchParams('', [],[],[]);
        this._searchParamSource = new BehaviorSubject<ISearchParams>(this.dataStore);
        this.searchParams = this._searchParamSource.asObservable();        
    }


    // called when the searchtextbox is updated in search component
    changeSearchString(searchString: string) {
        this.dataStore.SearchString = searchString;
        this._searchParamSource.next(Object.assign({}, this.dataStore));
    }


    setXYParams(lat, long) {  
        //console.log('searchparamstate.service setXYParams: ' + lat + '  ' + long);
        this.dataStore.SearchX = lat;
        this.dataStore.SearchY = long;
        this._searchParamSource.next(Object.assign({}, this.dataStore));

    }

}

然后在组件中我可以观察或贡献状态:

//inject service into component

...

searchstateService.data.subscribe(data => {
  //do what ever needs doing when data changes
})

...

//update the value of data in the service
searchstateService.changeSearchString('new search string);

推荐阅读