#angular #observable #angular-services #behaviorsubject
Вопрос:
Я создал беспорядок кода, пытаясь разобраться в том, как правильно использовать общие данные.
У меня есть служба, которая потребляет данные из других служб и возвращает вычисленный интерфейс. (IDriverProfile)
Проблема, с которой я сталкиваюсь, заключается в том, что я хочу потреблять все услуги сразу. Первоначально я использовал forkJoin для этого, и это отлично сработало. В тот момент, когда я попытался изменить данные, чтобы извлечь их из объекта поведения, как наблюдаемое, что-то сломалось.
Я совершенно уверен, что делаю что-то не так с combineLatest, но есть ли какой-то лучший способ подойти к этому? Это кажется довольно простым вариантом использования:
- Службы запросов для отфильтрованных данных
- Изменение данных на основе некоторого общего набора данных
- Объедините в расходуемый объект
- Компонент потребляет сервис DriverProfileService
Профиль водителя.Service.ts (Попытка 1)
Сбой из-за того, что соединение не завершается из объекта BehaviorSubject.
getDriverProfile(data:IDriverData): Observable<IDriverProfile>{
let driverStandings:IDriverStanding[] = [];
let driverQualifying:IQualifying[] = [];
let driverResults:IResult[] = [];
let careerStats:IDriverCareerStats;
let SeasonData:IDriverSeasonData[]=[];
let profile:IDriverProfile = {
driverData: data,
seasonsData: SeasonData,
careerStats: careerStats
};
// start forkJoin (works if all observables not utilizing shared data)
forkJoin({
QualyTask: this.qualifyService.getDriverQualifyingLaps(data.driver),
StandingsTask: this.driverStandingsService.getDriverStandings(data.driver),
ResultsTask: this.resultService.getDriverResults(data.driver),
RaceTask: this.raceService.getAllRaces(),
statusTask: this.statusService.status$,
teamsTask: this.teamsService.getAllConstructors()
}).subscribe(({QualyTask, StandingsTask, ResultsTask, RaceTask, statusTask, teamsTask})=>{
driverQualifying = QualyTask;
driverStandings = StandingsTask;
driverResults = ResultsTask;
let races = RaceTask;
let allStatus = statusTask;
let teams = teamsTask;
console.log('all status',allStatus);
let results = this.getResults(driverResults, races, driverStandings, allStatus, teams);
//console.log("results", results);
// calc career stats
profile.seasonsData = results.seasons;
profile.careerStats = results.stats;
});
console.log("profile", profile);
return of(profile);
}
Профиль водителя.Service.ts (попытка 2 combineLatest)
Not sure why this fails?
getDriverProfile(data:IDriverData): Observable<IDriverProfile>{
// this section is for trying combineLatest (broken)
let task1 = this.qualifyService.getDriverQualifyingLaps(data.driver);
let task2 = this.driverStandingsService.getDriverStandings(data.driver);
let task3 = this.resultService.getDriverResults(data.driver);
let task4 = this.raceService.getAllRaces();
let task5 = this.statusService.status$;
let task6 = this.teamsService.getAllConstructors();
const combine$ = combineLatest(task1, task2, task3, task4, task5, task6,
(t1,t2,t3,t4,t5,t6)=> {
let results = this.getResults(t3, t4, t2, t5, t6);
return <IDriverProfile> {
driverData: data,
seasonsData: results.seasons,
careerStats: results.stats
}
});
return combine$;
}
Статус.Сервис.ts
private readonly _StatusSource = new BehaviorSubject<IStatus[]>([]);
readonly status$ = this._StatusSource.asObservable();
constructor(private httpClient:HttpClient) {
this.loadInitialData();
}
loadInitialData() {
this.httpClient.get<IStatus[]>("assets/data/status.json").subscribe(x => {
//console.log('status load', x);
this._setStatus(x);
},
err => console.log("Error loading Status")
);
}
getStatus(): IStatus[] {
return this._StatusSource.getValue();
}
private _setStatus(status: IStatus[]): void {
this._StatusSource.next(status);
this._StatusSource.complete();
}
Комментарии:
1. Я начал читать это, но остановился после того, как у меня разболелась голова. Это не так уж много кода, я предлагаю спланировать, чего вы хотите и как вам нужно его использовать, а затем переписать это. Совершенно непонятно, почему вы используете и комбинируете последние и разветвленные соединения и, по-видимому, дважды выполняете одни и те же вызовы API.
2. Я могу прояснить это, я просто пытался включить оба набора кода, которые я пробовал. Сначала я попробовал раздвоение, затем, во-вторых, я попытался комбинировать. И то, и другое не дает желаемых результатов. forkJoin не выполняется из-за объекта «Поведение». тест на комбинацию, похоже, тоже не работает?
Ответ №1:
getDriverProfile
Метод, на который, как я предполагаю, подписывается в одном из ваших компонентов, когда вы упоминаете шаг 4: «Компонент использует DriverProfileService».
Профиль водителя.Service.ts обновит метод до следующего:
// Assuming everything within the combine latest call are observables.
getDriverProfile(data:IDriverData): Observable<IDriverProfile> {
return Observable.combineLatest(
this.qualifyService.getDriverQualifyingLaps(data.driver),
this.driverStandingsService.getDriverStandings(data.driver),
this.resultService.getDriverResults(data.driver),
this.raceService.getAllRaces(),
this.statusService.getStatusSource(),
this.teamsService.getAllConstructors()
).map((t1,t2,t3,t4,t5,t6) => {
// I assume getResults is not an observable, it just transforms data or something.
let results = this.getResults(t3, t4, t2, t5, t6);
return <IDriverProfile> {
driverData: data,
seasonsData: results.seasons,
careerStats: results.stats
}
});
}
Что касается вашего Статуса.Service.ts позволяет упростить процесс:
// Declare your subject and set value to empty array
private statusSource = new BehaviorSubject<IStatus[]>([]);
// Contructor calling the method to get data initially
constructor(private httpClient:HttpClient) {
this.loadInitialData();
}
loadInitialData() {
this.httpClient.get<IStatus[]>("assets/data/status.json")
.subscribe(statusSource => {
this.setStatusSource(statusSource);
},(error) => console.log(error));
}
// Gets the status source
getStatusSource(): Observable<IStatus[]> {
return this.statusSource.asObservable();
}
// Sets the status source
public setStatusSource(statusSource: IStatus[]): void {
this.statusSource.next(statusSource);
}
Комментарии:
1. Спасибо, это привело меня туда, куда я направлялся. Ваше здоровье!