Angular 如何基于两个不同的异步方法结果设置结果

Angular 如何基于两个不同的异步方法结果设置结果,angular,rxjs,angular2-services,Angular,Rxjs,Angular2 Services,在我的数据服务中,我有: //Observables currentTicket$: Observable<Ticket>; ticketTypes$: Observable<Array<TicketType>>; currentTicketSurvey$: Observable<TicketSurvey>; //observers private _ticketTypesObserver: any; private _currentTicke

在我的数据服务中,我有:

//Observables
currentTicket$: Observable<Ticket>;
ticketTypes$: Observable<Array<TicketType>>;
currentTicketSurvey$: Observable<TicketSurvey>;


//observers
private _ticketTypesObserver: any;
private _currentTicketSurveyObserver: any;
private _currentTicketObserver: any;

private _dataStore: {
    currentTicket: Ticket,
    ticketTypes: Array<TicketType>,
    currentTicketSurvey: TicketSurvey
}

constructor(private http: Http){
//set up observables
this.currentTicket$ = new Observable(observer=> this._currentTicketObserver = observer).share();
    this.ticketTypes$ = new Observable(observer=> this._ticketTypesObserver = observer).share();
    this.currentTicketSurvey$ = new Observable(observer=> this._currentTicketSurveyObserver = observer).share();


//init datastore
this._dataStore = {
        currentTicket: null,
        ticketTypes: [],
        currentTicketSurvey: null
    };
}



//Data Retrieval Methods

getTicketTypes() {
    if (this._dataStore.ticketTypes.length > 0) //if we already have ticket types, don't refresh.  Static Data.
        return;

    this.http.get('http://localhost:65421/tickets/GetTicketTypes/')
        .map(res => (<Response>res).json())
        .map((types: Array<any>) => {
            let result: Array<TicketType> = [];
            if (types) {
                types.forEach(ticketType => {
                    result.push(
                        new TicketType(
                            ticketType.Description
                            , ticketType.Id
                            , ticketType.IsDisplayed
                        ));
                });
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.ticketTypes = data;
            this._ticketTypesObserver.next(this._dataStore.ticketTypes);
        },
        err => {
            console.log(err);
        }
        );
}


getTicketSurvey(ticketId:string) {

    this.http.get('http://localhost:65421/tickets/GetTicketById/' + ticketId)
        .map(res => (<Response>res).json())
        .map((survey: TicketSurvey) => {
            let result: TicketSurvey = null;
            if (survey) {
                result = new TicketSurvey(
                    survey.id,
                    survey.ticketId,
                    survey.ticketTypeId
                );
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.currentTicketSurvey = data;
            this._currentTicketSurveyObserver.next(this._dataStore.currentTicketSurvey);
        },
        err => {
            console.log(err);
        }
        );
}


getTicketById(id:string) {
    this.http.get('http://localhost:65421/tickets/GetTicketById/' + id)
        .map(res => (<Response>res).json())
        .map((ticketRes: Ticket) => {
            let result: Ticket = null;
            if (ticketRes) {
                result = new Ticket(
                    //Set constructor values
                );
            }

            return result;
        }).
        subscribe(
        data => {
            this._dataStore.currentTicket = data;
            this._currentTicketObserver.next(this._dataStore.currentTicket);
        },
        err => {
            console.log(err);
        }
        );
}
//可观测
currentTicket$:可观察到;
ticketTypes$:可观察;
currentTicketSurvey$:可观察到;
//观察员
私有_ticketTypesObserver:any;
private _CurrentTicketServeyObserver:任何;
private _CurrentTicketTobServer:任何;
专用数据存储:{
当前票证:票证,
票证类型:数组,
当前TicketSurvey:TicketSurvey
}
构造函数(专用http:http){
//设置可观察对象
this.currentTicket$=新的可观察对象(observer=>this.\u currentTicketTobServer=observer).share();
this.ticketTypes$=新的可观察对象(observer=>this.\u ticketTypesObserver=observer).share();
this.CurrentTicketCurvey$=新的可观察对象(observer=>this.\u CurrentTicketCurveyObserver=observer).share();
//初始化数据存储
此。_数据存储={
当前票证:空,
票务类型:[],
currentTicketSurvey:空
};
}
//数据检索方法
getTicketTypes(){
if(this.\u dataStore.ticketTypes.length>0)//如果已经有票证类型,请不要刷新.Static数据。
返回;
this.http.get('http://localhost:65421/tickets/GetTicketTypes/')
.map(res=>(res.json())
.map((类型:数组)=>{
让结果:数组=[];
如果(类型){
types.forEach(ticketType=>{
结果:推(
新票号类型(
ticketType.Description
,ticketType.Id
,ticketType.isplayed
));
});
}
返回结果;
}).
订阅(
数据=>{
这._dataStore.ticketTypes=数据;
this.\u ticketTypesObserver.next(this.\u dataStore.ticketTypes);
},
错误=>{
控制台日志(err);
}
);
}
getTicketSurvey(ticketId:string){
this.http.get('http://localhost:65421/tickets/GetTicketById/“+TICKTID)
.map(res=>(res.json())
.map((调查:TicketSurvey)=>{
let结果:TicketSurvey=null;
国际单项体育联合会(调查){
结果=新的TicketSurvey(
调查编号:,
survey.ticketId,
survey.ticketTypeId
);
}
返回结果;
}).
订阅(
数据=>{
这是。_dataStore.currentTicketSurvey=数据;
this.\u currentTicketServeyObserver.next(this.\u dataStore.currentTicketSurvey);
},
错误=>{
控制台日志(err);
}
);
}
getTicketById(id:string){
this.http.get('http://localhost:65421/tickets/GetTicketById/“+id)
.map(res=>(res.json())
.map((票证:票证)=>{
let结果:票证=null;
如果(票务){
结果=新票(
//设置构造函数值
);
}
返回结果;
}).
订阅(
数据=>{
此._dataStore.currentTicket=数据;
this.\u currentTicketTobServer.next(this.\u dataStore.currentTicket);
},
错误=>{
控制台日志(err);
}
);
}
我的组件有:

currTicket: Ticket;
ticketTypes: Array<TicketType>;
currTicketType: TicketType;
currTicketSurvey: TicketSurvey;


ngOnInit() {
    this.ticketDataService.currentTicket$.subscribe(cTicket => this.currTicket = cTicket);
    this.ticketDataService.ticketTypes$.subscribe(tTypes => this.ticketTypes = tTypes);
    this.ticketDataService.currentTicketSurvey$.subscribe(cSurvey => this.currTicketSurvey = cSurvey);

    this.load();
}

load()
{
    this.ticketDataService.getTicketById(this._routeParams.get('id'));
    this._ticketDataService.getTicketTypes();
    this._ticketDataService.getTicketSurvey(this._routeParams.get('id'));

    //////************ Need something here to set the current ticket type

    //this.ticketTypes.forEach((tType)=>{
    //    if(tType.id == this.currTicketSurvey.ticketTypeId)
    //    this.currTicketType = tType;
    //    return;
    //});

}
currenticket:Ticket;
票证类型:数组;
currTicketType:TicketType;
currTicketSurvey:TicketSurvey;
恩戈尼尼特(){
this.ticketDataService.currentTicket$.subscribe(cTicket=>this.currTicket=cTicket);
this.ticketDataService.ticketTypes$.subscribe(tTypes=>this.ticketTypes=tTypes);
this.ticketDataService.currentTicketSurvey$.subscribe(cSurvey=>this.currTicketSurvey=cSurvey);
这个.load();
}
加载()
{
this.ticketDataService.getTicketById(this.\u routepams.get('id');
这是。_ticketDataService.getTicketTypes();
this._ticketDataService.getTicketSurvey(this._routeParams.get('id'));
//////************需要在此处设置当前票证类型吗
//this.ticketTypes.forEach((tType)=>{
//if(tType.id==this.currTicketSurvey.ticketTypeId)
//this.currTicketType=tType;
//返回;
//});
}
我遇到的问题是如何在组件中设置currentTicketType?这取决于已加载的CurrentTicketCurvey和已加载的ticketTypes。在我的代码的其他区域中,这些调用可能一起调用,也可能不一起调用,因为它们是异步调用,所以我不能在调用服务后立即设置它们。在淘汰赛中,我想我可以设置一个计算的可观测值,然后用它来完成。我找不到角2的等价物。如何处理这种情况,以便在加载其他对象后设置currentTicketType

当然它经常出现。我看到的例子很相似,但不是相同的,比如说使用defer和concatAll,但是看起来好像它会假设这些方法总是以相同的顺序或在相同的时间被调用。我只是还没能拼凑出我要找的东西。

RxJS提供了一套可观察的。我认为,
forkJoin
可观察。merge
可以满足您的需要

  • Observable.forkJoin
    将等待一组Observable接收到事件(每个事件):

  • 可观察。合并
    。当接收到2个结果时,流关闭

    Observable.merge(obs1, obs2)
     .take(2)
     .subscribe({complete: () => { ... });
    
这个问题可以给你一些额外的提示:


我会将此标记为答案,即使我的代码无法运行。我认为我的代码不起作用的原因与此无关。谢谢你的帮助。
Observable.merge(obs1, obs2)
 .take(2)
 .subscribe({complete: () => { ... });