Я хочу передать некоторые данные из одного модуля в другой модуль. Для этого я использую Тему. Я создал тему ниже:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SelectedClusterService {
constructor() { }
public selectedClusterName = new Subject<string>();
}
Я передаю некоторые данные из «oneComponent» через вышеуказанную службу и перенаправляюсь на «anotherComponent»:
this.selectedClusterService.selectedClusterName.next(cluster_name);
И получение данных в «otherComponent» следующим образом:
this.selectedClusterService.selectedClusterName.subscribe(res => {
this.selectedCluster = res;
console.info("this.selectedCluster", this.selectedCluster);
});
Это работает нормально, я получаю данные в «другой компонент». Но в «otherComponent» я использую forkJoin. Я хочу получить данные от субъекта только после получения данных от forkJoin. Я пытаюсь так:
ngOnInit() {
forkJoin([
this.dataService.getUpgradeAppList(),
this.dataService.getClusterList()
]).subscribe((data: any) => {
console.info("forkJoin :: ngOnInit ::", data);
this.appList = data[0].apps;
this.clusterList = data[1];
});
this.selectedClusterService.selectedClusterName.subscribe(res => {
this.selectedCluster = res;
console.info("this.selectedCluster", this.selectedCluster);
});
}
Я пробовал ngAfterViewInit, ngAfterContentChecked с помощью ChangeDetection, а также пытаюсь использовать setTimeout, но ничего не получается. Всегда сначала я получаю данные субъекта, а затем данные forkJoin.
Как я могу сначала получить forkJoin, а затем данные субъекта?
Любая помощь приветствуется...
@EvgenyGurevich тот же результат после использования mergeLatest





Прежде всего, невозможно гарантировать последовательность получения данных в вашем компоненте при работе с асинхронными сущностями. Я бы использовал BehaviorSubject вместо Subject, чтобы гарантировать получение данных от другого компонента.
Ваш сервис будет таким:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SelectedClusterService {
constructor() { }
public readonly selectedClusterName = new BehaviorSubject<string | undefined>(undefined);
}
Ваш компонент:
ngOnInit() {
forkJoin([
this.dataService.getUpgradeAppList(),
this.dataService.getClusterList()
]).
pipe(
tap((data: any) => {
console.info("forkJoin :: ngOnInit ::", data);
this.appList = data[0].apps;
this.clusterList = data[1];
}),
switchMap(() => this.selectedClusterService.selectedClusterName),
filter(res => res !== undefined)
).subscribe(res => {
this.selectedCluster = res;
console.info("this.selectedCluster", this.selectedCluster);
});
}
В вашем anotherComponent вы можете использовать оператор switchMap, чтобы начать получать данные из oneComponent, и filter, чтобы игнорировать начальное значение в BehaviorSubject, которое мы установили в undefined.
Большое спасибо.. Работает, как и ожидалось. Я попробовал одно решение, которое применяет setTimeout при отправке данных из «oneComponent», и оно тоже работает. Но ваше решение намного лучше моего.
Попробуйте использовать joinLatest вместо forkJoin.