這是一個奇怪的...我有一個單例(providedIn:“root”)服務,它有一個 BehaviorSubject,它是私有的,但作??為一個 observable 公開:
private readonly _caseData$ = new BehaviorSubject<CaseData | null>(null);
Context = this.caseData$.asObservable();
背景關系由另一個函式設定,該函式在主題上呼叫下一個,然后從背景關系中檢索值。
在一個組件中,我有一個接受值的函式,并且從 Context 中通過管道從 CaseData 上的陣列中洗掉一些值并呼叫服務中的另一個函式:
unassign = (tag: Tag) => {
this.caseContext.Context.pipe(
switchMap((caseData) => {
const index = caseData.tags.findIndex(tagId => tagId === tag.tagId);
if (index > -1) {
caseData.tags.splice(index, 1);
}
return of(caseData);
}),
concatMap((caseData: CaseData) => {
return this.caseContext.patchCase(caseData);
})
)
}
這很好用,但是當我呼叫 patchCase 并訂閱該函式中的行為主題時,它已經改變了。上面switchMap中被移除的標簽,在行為主體的CaseData中也被移除了。
public patchCase(updated: CaseData): Observable<CaseData> {
return of(updated).pipe(
mergeMap((changed: CaseData) => {
return combineLatest([this._caseData$, of(changed)]);
}),
map(([original, changed]: [CaseData, CaseData]) => {
^- this value has the tags removed that were removed in the previous function.
return {
caseId: changed.caseId,
operations: createPatch(original, changed)
};
}),
concatMap((caseOperations: { caseId: string; operations: Operation[] }) => {
return this._caseApi.patch(caseOperations.caseId, caseOperations.operations);
}),
tap((updated: CaseData) => {
this.load(updated.caseId);
})
);
}
我確定有比我上面的更好的方法來構建整個事情,并且我可以通過在洗掉標簽之前在 unassign 函式中復制物件來解決這個問題,但是為什么案例資料會在我在另一個可觀察的流中更改它,該流從可觀察的流中流出,甚至沒有觸及行為主題?如果這是意料之中的,除了制作副本之外,有沒有更好的方法來做這種事情而不改變主題的價值?
uj5u.com熱心網友回復:
因為這條線而發生
caseData.tags.splice(index, 1);
在這種情況下,.tags陣列發生了變異。要擺脫它,請嘗試像這樣修改您的代碼:
unassign = (tag: Tag) => {
this.caseContext.Context.pipe(
map((caseData) => ({
...caseData,
tags: caseData.tags.filter(tagId => tagId !== tag.tagId)
})),
concatMap((caseData: CaseData) => {
return this.caseContext.patchCase(caseData);
})
)
}
switchMap 在這里沒用,因為您基本上是將簡單值映射到簡單值,而不是可觀察值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/431912.html
