[英]Angular 8: Why is my non-observable type getting updated whenever the data from which it was copied is updated?
使用Angular 8和Ngrx 8(無關緊要,但是為了完整性),我有一個狀態服務來管理我的視圖模型狀態。 在其中,我具有viewModel $屬性,這是一個行為主題。 當服務最初獲取其數據時,將使用新的視圖模型值調用viewModel $ .next(),並將另一個名為originalValue的屬性設置為該視圖模型值。 很好 我想發生的事情以及我認為已經編寫的代碼,都是為了使原始值保持不變,因此,如果我的用戶想要還原更改,我只需丟棄更新的視圖模型並將其設置回原始值即可。
實際發生的情況是,每當我更新視圖模型時,originalValue屬性也會(錯誤地)被更新。 這令人費解,因為originalValue屬性不是可觀察的。 我猜想它與閉包有關,但是我還不足以使它困惑。
底線問題-為什么會發生這種情況,我該如何解決? 如何獲得所需的功能-即保留舊版本的數據,以便在必要時可以還原它? (您可能想知道為什么我不只是再次從商店中檢索數據。我可以/可以這樣做,並且可以正常工作,但是無論如何我想了解這里出了什么問題。我有一個“項目“需要同時還原,並且如果可以避免的話,我不想花費額外的時間/費用將狀態模型轉換為視圖模型。)
以下是相關代碼:
在國家服務中
特性:
public viewModel$: BehaviorSubject<ProjectCoreViewModel>;
public viewModelLoaded$: BehaviorSubject<boolean> = new BehaviorSubject(false);
public originalValue: ProjectCoreViewModel;
public isPristine$: BehaviorSubject<boolean> = new BehaviorSubject(true);
private isInitialized = false;
數據的初始選擇(通過立面從存儲中檢索)
public selectData() {
this.facade.getProjectCore()
.subscribe(core => this.fromStoreStateModel(core));
}
從狀態模型轉換為視圖模型,然后調用updateViewModel $方法:
fromStoreStateModel(projectCore: ProjectCore) {
if (projectCore) {
const viewModel: ProjectCoreViewModel = {
projectId : projectCore.projectId,
studioId : this.facade.studioId,
ravelryProjectId : projectCore.ravelryProjectId,
ravelryLink : projectCore.ravelryLink,
isPrivate : false,
title : projectCore.projectTitle,
startedDate : projectCore.startedDate,
completedDate : projectCore.completedDate,
warpingMethod : projectCore.warpingMethodId,
weavingTechnique : projectCore.weavingTechniqueId,
reedId : projectCore.reedId,
loomId : projectCore.loomId,
itemCategory : projectCore.itemCategoryId,
itemQuantity : projectCore.quantity,
designName : projectCore.designName,
sourcePublicationId : projectCore.sourcePublicationId,
itemWidth : projectCore.itemWidth,
itemLength : projectCore.itemLength,
widthHeightRatio : this.getSizeRatio(projectCore),
coreNotes : projectCore.coreNotes,
sourcePublicationReference: projectCore.sourcePublicationReference,
};
this.updateViewModel$(viewModel);
}
}
updateViewModel $方法:
updateViewModel$(value: ProjectCoreViewModel) {
if (value) {
if (!this.viewModel$) {
if (!this.isInitialized) {
this.setOriginalValue(value);
this.viewModel$ = new BehaviorSubject(value);
this.viewModel$.pipe(
skip(1)).subscribe(model => {
console.log('changed core view model', model);
console.log('original value in state service', this.originalValue); // this has changed too!
this.isPristine$.next(false);
});
this.isInitialized = true;
}
} else {
this.isPristine$.next(false);
this.viewModel$.next(value);
}
this.setLoadedStatus(true);
} else {
this.setLoadedStatus(false);
}
}
setOriginalValue方法:
private setOriginalValue(viewModel: ProjectCoreViewModel) {
this.originalValue = viewModel;
this.isPristine$.next(true);
}
在我的組件中,這部分更新了視圖模型:
this.coreForm.valueChanges.pipe(debounceTime(1000))
.subscribe(value => {
model.title = value.name;
model.startedDate = value.startedDate;
model.completedDate = value.completedDate;
model.itemCategory = value.itemType;
model.weavingTechnique = value.weavingTechnique;
model.warpingMethod = value.warpingMethod;
model.reedId = value.reed;
model.loomId = value.loom;
model.itemQuantity = value.quantity;
model.designName = value.designName;
model.sourcePublicationId = value.designSource;
model.sourcePublicationReference = value.designSourceReference;
model.itemWidth = value.itemWidth;
model.itemLength = value.itemLength;
this.projectCoreViewModel$.next(model);
});
這不是閉包,我想您只是在2個地方共享同一對象,並在一個地方修改它,所以在另一個地方也將對其進行更新。
要解決將其保存到this.originalValue
時嘗試復制它的this.originalValue
,可以通過切換以下行來實現:
this.originalValue = viewModel;
到這個:
this.originalValue = {...viewModel};
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.