簡體   English   中英

角8:為什么每當從其復制數據的數據被更新時,我的不可觀察類型都會被更新?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM