вы можете использовать Subject
(http://reactivex.io/rxjs/class/es6/Subject.js~Subject.html)
Я создал очень упрощенный стек, чтобы показать, как он работает
https://stackblitz.com/edit/angular-zyvkpu?file=src%2Fapp%2Fapp.component.ts
см. Вывод консоли для проверки.
здесь соответствующая часть кода (адаптирована к вашему случаю, а не 1: 1 от stackblitz)
@Injectable()
export abstract class PageDetailsAbstract<T> implements OnInit {
object: string;
id: number;
details$: Subject<T> = new Subject<T>();
constructor(
protected entitiesSelectors: EntitiesSelectors) {
}
ngOnInit() {
this.route.params
.pipe(
map(resp => +resp.id),
)
.subscribe(resp => {
this.id = resp;
this.adopt();
});
}
protected adopt() {
if (this.id) {
this.entitiesSelectors.details(this.object, this.id).subscribe((detail: T) => {
this.details$.next(detail);
});
}
}
лично я бы немного перестроил код.
это очиститель ставок, потому что вы не будете вкладывать несколько звонков на subscribe
и не будете полагаться (по крайней мере, не так сильно) на this.id
, который существует вне потока rxjs.
до
@Injectable()
export abstract class PageDetailsAbstract<T> implements OnInit {
object: string;
id: number;
details$: Subject<T> = new Subject<T>();
constructor(
protected entitiesSelectors: EntitiesSelectors) {
}
ngOnInit() {
this.route.params
.pipe(
mergeMap((resp: any) => {
return this.adopt(+resp.id);
}))
.subscribe((detail: T) => {
this.details$.next(detail);
});
}
protected adopt(id: number): Observable<T> {
if (this.id) {
return this.entitiesSelectors.details(this.object, this.id);
}
else {
return of(null); // or whatever is appropriate in your case (e.g. EMPTY or something)
}
}
ваш дочерний класс останется прежним.
почему
почему ваш пример не работает:
Я думаю, что это потому, что details$
- наблюдаемая холодность. (https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html)
когда вы переназначаете details$
, вы создаете новую наблюдаемую, а ранее сделанная подписка не имеет смысла, потому что она была для другой наблюдаемой. Вам нужно будет подписаться заново.
Subject
является горячей наблюдаемой.
Возможно, вы могли бы также использовать что-то вроде publish
или share
, чтобы преобразовать вашу холодную наблюдаемую в горячую.