摘要:因為我們正好要使用,此時我們就可以用的服務來監聽了當然,我們不能忘了清空訂閱最后一步就是在有返回的時候調用表單的現在我們可以在組件里顯示提醒了
原文:Connect Angular Forms to @ngrx/store
這篇文章中,我們將要討論如何用ngrx/effects連接Angular表單和ngrx/store
我們最終的結果是這樣的
ew-story0.component.ts @Component({ selector: "new-story-form", template: `
方便起見,我們會寫一個簡單的reducer來組織管理我們應用里的所有的表單
狀態(the state)將由一個用ID作為key,表格數據作為value的簡單對象構成
舉個例子
connect-form.reducer.ts const initialState = { newStory: { title: "", description: "" }, contactUs: { email: "", message: "" } } export function forms(state = initialState, action) { }
我們先構建一個action——UPDATE_FORM。這個action由兩個key:path和value組成
connect-form1.reducer.ts store.dispatch({ type: UPDATE_FORM, payload: { path: "newStory", value: formValue } });
然后這個reducer將負責更新state
connect-form2.reducer.ts export function forms(state = initialState, action) { if(action.type === UPDATE_FORM) { // newStory: formValue return { ...state, [action.payload.path]: action.payload.value } } }連接表單的組件——ConnectForm Directive 獲取State
我們想要基于state更新表單,所以我們需要path作為輸入,然后取出store中正確的片段
connect-form.directive.ts @Directive({ selector: "[connectForm]" }) export class ConnectFormDirective { @Input("connectForm") path: string; constructor(private formGroupDirective: FormGroupDirective, private store: Store) { ngOnInit() { // Update the form value based on the state this.store.select(state => state.forms[this.path]).take(1).subscribe(formValue => { this.formGroupDirective.form.patchValue(formValue); }); } } }
我們抓取表單directive實例然后從store里更新表單數據
更新State當表單數據改變時我們也需要更新表單狀態。我們可以通過訂閱(subscribe)這個valueChanges的可觀察對象(observable)然后調度(dispatch)這個UPDATE_FORM的action來獲取值
connect-form1.directive.ts this.formChange = this.formGroupDirective.form.valueChanges .subscribe(value => { this.store.dispatch({ type: UPDATE_FORM, payload: { value, path: this.path, // newStory } }); })
這就是表單和State同步所要做的全部工作了
通知和重置有兩件事我們要在這個部分完成
基于HTTP響應返回來顯示通知給用戶——我們需要保證通知直接傳給組件并且不儲存信息在store里
有兩點原因
通常,沒有其他的組件需要這個信息
我們不想每次都重置store
當提交成功時重置表單
我們將讓Angular盡其所能,處理好前端表單校驗并重置表單
成功的Action成功的Action包含表單的path屬性所以我們可以知道到底哪個表單需要重置,同時什么時候需要去使用(emit)這個成功的事件
connect-form2.directive.ts const FORM_SUBMIT_SUCCESS = "FORM_SUBMIT_SUCCESS"; const FORM_SUBMIT_ERROR = "FORM_SUBMIT_ERROR"; const UPDATE_FORM = "UPDATE_FORM"; export const formSuccessAction = path => ({ type: FORM_SUBMIT_SUCCESS, payload: { path } });異常的Action
同成功的action一樣,因為有path的存在,我們也知道何時去使用(emit)錯誤異常 的事件
connect-form3.directive.ts export const formErrorAction = ( path, error ) => ({ type: FORM_SUBMIT_ERROR, payload: { path, error } });
我們需要創建 成功 和 錯誤異常 的輸出 然后 監聽 FORM_SUBMIT_ERROR 和 FORM_SUBMIT_SUCCESS 的 action。
因為我們正好要使用 ngrx/effects ,此時我們就可以用 Action 的服務(service)來監聽actions了
connect-form3.directive.ts @Directive({ selector: "[connectForm]" }) export class ConnectFormDirective { @Input("connectForm") path : string; @Input() debounce : number = 300; @Output() error = new EventEmitter(); @Output() success = new EventEmitter(); formChange : Subscription; formSuccess : Subscription; formError : Subscription; constructor( private formGroupDirective : FormGroupDirective, private actions$ : Actions, private store : Store) { } ngOnInit() { this.store.select(state => state.forms[this.path]) .debounceTime(this.debounce) .take(1).subscribe(val => { this.formGroupDirective.form.patchValue(val); }); this.formChange = this.formGroupDirective.form.valueChanges .debounceTime(this.debounce).subscribe(value => { this.store.dispatch({ type: UPDATE_FORM, payload: { value, path: this.path, } }); }); this.formSuccess = this.actions$ .ofType(FORM_SUBMIT_SUCCESS) .filter(( { payload } ) => payload.path === this.path) .subscribe(() => { this.formGroupDirective.form.reset(); this.success.emit(); }); this.formError = this.actions$ .ofType(FORM_SUBMIT_ERROR) .filter(( { payload } ) => payload.path === this.path) .subscribe(( { payload } ) => this.error.emit(payload.error)) } }
當然,我們不能忘了清空訂閱
connect-form4.directive.ts ngOnDestroy() { this.formChange.unsubscribe(); this.formError.unsubscribe(); this.formSuccess.unsubscribe(); }
最后一步就是在有返回的時候調用表單的actions
connect-form4.directive.ts import { formErrorAction, formSuccessAction } from "../connect-form.directive"; @Effect() addStory$ = this.actions$ .ofType(ADD_STORY) .switchMap(action => this.storyService.add(action.payload) .switchMap(story => (Observable.from([{ type: "ADD_STORY_SUCCESS" }, formSuccessAction("newStory")]))) .catch(err => (Observable.of(formErrorAction("newStory", err)))) )
現在我們可以在組件里顯示提醒了
ew-story.component.ts @Component({ selector: "new-story-form", template: `
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84215.html
摘要:來源于社區,時至今日已經基本成為的標配了。部分很簡單,要根據傳入的執行不同的操作。當性能遇到瓶頸時基本不會遇到,可以更改,保證傳入數據來提升性能。當不再能滿足程序開發的要求時,可以嘗試使用進行函數式編程。 Immutable & Redux in Angular Way 寫在前面 AngularJS 1.x版本作為上一代MVVM的框架取得了巨大的成功,現在一提到Angular,哪怕是已...
摘要:延伸閱讀學習與實踐資料索引與前端工程化實踐前端每周清單半年盤點之篇前端每周清單半年盤點之與篇前端每周清單半年盤點之篇 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關注【前端之巔】微信公眾號(ID:frontshow),及時獲取前端每周清單;本文則是對于半年來發布的前端每周清單...
摘要:目前電商領域有兩款比較出名的開源電商網站解決方案,分別是基于開發框架,代號為的開源項目,以及基于的作為開源項目的開發成員之一,今天我想通過本文,給大家介紹一下我們平時購物時最常使用到的功能之一,添加產品到購物車的技術實現。 目前電商領域有兩款比較出名的開源電商網站解決方案,分別是基于 Angular 開發框架,...
摘要:首先,我們需要在入口頁面的中配置根路徑然后創建一個路由模塊路由配置在主模塊中導入配置好的路由模塊而在頁面中需要一個容器去承載上面代碼中的定義了用戶點擊后的路由跳轉,定義該路由激活時的樣式類。 剛實習的時候用過AngularJS,那時候真的是連原生JavaScript都不會寫,依樣畫葫蘆做了幾個管理后臺。然后突然換項目了,AngularJS就不寫了,感覺前前后后接觸了一年多的Angula...
摘要:前端日報精選精讀個最佳特性翻譯輕量級函數式編程第章組合函數之組件類型寫的姿勢中文周二放送面試題詳解知乎專欄譯原生值得學習嗎答案是肯定的掘金個超贊的視覺效果眾成翻譯布局時常見總結騰訊前端團隊社區歸檔打地鼠入門學習書籍 2017-08-30 前端日報 精選 精讀《Web fonts: when you need them, when you don’t》10個最佳ES6特性翻譯 -《Jav...
閱讀 3318·2023-04-25 16:25
閱讀 3823·2021-11-15 18:01
閱讀 1600·2021-09-10 11:21
閱讀 3007·2021-08-02 16:53
閱讀 3081·2019-08-30 15:55
閱讀 2489·2019-08-29 16:24
閱讀 2098·2019-08-29 13:14
閱讀 1027·2019-08-29 13:00