#javascript #angular #observable #angular10 #behaviorsubject
#javascript #angular #наблюдаемый #angular10 #behaviorsubject
Вопрос:
У меня есть 1 функциональный модуль ( Fund module
), который отображает данные фонда в одном из его компонентов, и AppModule
который отображает данные советника. Данные фонда и данные советника имеют отношение один ко многим. Компонент Fund получает данные из сервисов, определенных в AppModule.
Данные передаются в модуль Fund с использованием BehaviorSubject
as data, который может измениться, если пользователь обновит или изменит данные в AppModule. Подписка на данные работает некорректно. Модуль fund отображает только значение (10), с которым BehaviorSubject
инициализируется. Он не отображает обновленное значение (100), и подписка не работает должным образом для отображения значений во второй раз.
Вот код:
Сервис в AppModule:
test = new BehaviorSubject<number>(10);
getTest(): Observable<number> {
return this.test.asObservable();
}
public updateLocalData(sleeves: Sleeve[]): void {
.... update logic
this.test.next(100);
}
FundDataComponent в модуле Fund
changeDetection: ChangeDetectionStrategy.OnPush,
ngOnInit(): void {
this.test = this.service.getTest().subscribe((number) => {
this.number = number;
console.log(number); // get's called only once to display 10
});
}
Комментарии:
1. Загружается ли модуль fund лениво?
2. Где вы вызываете updateLocalData?
3. @korteee нет, он не загружается лениво
4. @WillAlexander Я вызываю updateLocalData в одном из компонентов (EditDataComponent) в AppModule
5. не могли бы вы воспроизвести это на stackblitz?
Ответ №1:
Создайте model — resource.ts:
import { BehaviorSubject, Observable } from 'rxjs';
import { refCount, publishReplay } from 'rxjs/operators';
export class StreamResource {
private loading = false;
private behaviorSubject: BehaviorSubject<any>;
public readonly obs: Observable<any>;
constructor(defaultValue?: any) {
this.behaviorSubject = new BehaviorSubject(defaultValue);
this.obs = this.behaviorSubject.asObservable().pipe(publishReplay(1), refCount());
}
request(method: any): void {
if (method amp;amp; !this.loading) {
this.loading = true;
method().toPromise().then((data: any) => {
if (data) { this.update(data); }
this.loading = false;
});
}
}
getValue() {
return this.behaviorSubject.getValue();
}
update(data: any) {
this.behaviorSubject.next(data);
}
refresh() {
const data = this.getValue();
if (data) { this.update(data); }
}
}
Создайте StreamService
import { StreamResource } from '../models/resource';
public test = new StreamResource(10);
...
getTest() {
this.test.request(() => this.testService.getTest());
}
Как использовать?
constructor(private streamService: StreamService) { }
ngOnInit() {
this.streamService.test.obs.subscribe((data: any) => {
if (!data) {
return this.streamService.getTest();
} else {
this.test = data;
}
});
Комментарии:
1. @PritamBohra github.com/dm-grinko/angular-rxjs-template