簡體   English   中英

angular + redux / ngrx:狀態更新與表單

[英]angular + redux/ngrx: state update vs. forms

首先,我正在使用:

現在類似於反應現實世界的例子,我有一片專用於實體的狀態,這實際上是要求denormalize()方法工作,因為文章可以有一個author ,或者media本身都可以是實體。

這意味着當我選擇一個來自我的州的單個user ,我正抓住這個全局的實體片段,我的選擇器看起來像這樣

export const getOne = createSelector(
  getAllEntities,
  getDetailId,
  (entities, id) => denormalize(id, schema, entities)
);

然后從ngrx / store“選擇”

state.map(getOne).distinctUntilChanged()

現在填寫我的表格我這樣做(半偽代碼)

class Cmp {
  form = new FormGroup({ /* whatever */});
  user$ = this._store.map(getOne).distinctUntilChanged();

  constructor(private _store: Store<AppState>) {
    this.user$.subscribe((data) => {
      this.form.patchValue(data);
    });
  }
}

結合重新選擇和map / distincUntilChanged我幾乎可以在任何實體更改時獲得新的更新,所以請考慮這種情況..

  • 您訪問文章ID 5,它將填充訂閱由全局實體切片組成的商店切片
  • 你開始編輯“ textFormControl
  • 其他人更改了ID為3的用戶,並且您通過websockets接收更新,導致subscribe觸發(因為全局實體切片已更改)並覆蓋您在編輯時更改的任何值,使用當前存儲中的值(舊值) )

..這個websocket有很多不同的情況可以導致更新更新。

在redux世界中是否有任何模式可以解決這個問題,或者ngrx世界中的任何人都必須處理這個問題? 我想到的唯一明智的事情就是在輸入時保存商店的任何價值,這需要掛鈎角度反應形式來存儲,這是屁股的巨大痛苦,並且ngrx /表格不會很快到來。 但我確信有人必須已經提出了一些簡單的解決方案。

謝謝!

(你可以閱讀關於gitter的后續討論)

考慮將表單的狀態與規范化實體分開存儲。 例如,您的州可以包含諸如articleEditForm的屬性或類似的東西。 根據路由器狀態的訂閱獲取文章的ID,將combineLatest與商店的當前狀態一起發送,使用文章的有效負載調度“EDIT_ARTICLE”類型的操作。 然后,reducer將使用article state payload在您的商店狀態上設置articleEditForm屬性。 原始規范化實體只有在成功提交表單后才會更新 - 可能使用articleEditForm的值或表單提交給服務的響應。 這種方法的優點是可以在redux存儲庫中使用表單的狀態,以獲得更復雜的顯示和驗證方案。 每次擊鍵,輸入更改,表單提交或滿足您的用例需求的任何內容都可以在redux中更新這些值。

這對於80%的簡單形式來說是過度的 - 可以直接從商店中的規范化實體填充表單(可能使用.take(1)或使用路由器狀態和combineLatest與store來管理並發問題)。 然而,即使只使用香草形式,狀態仍然與商店中的規范化實體分開管理 - 這是IMO問題的准確模型。

到目前為止,我們通過在輸入模糊上更新商店來處理這個問題(所以不是每次擊鍵都是如此)。

class Cmp {
    form = new FormGroup({ /* whatever */});

    constructor(private _store: Store<AppState>) {
        this._store.select(getOne)
                   .take(1) // we don't listen to changes
                   .subscribe((data) => {
                       this.form.patchValue(data);
                   });
    }

    onInputBlur() {
        this._store.dispatch({ type: 'UPDATE_USER', payload: this.form.value });
    }
}

然后我們將onBlur事件添加到我們的輸入中

<input (blur)="onInputBlur()" formControlName="firstname">

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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