摘要:因?yàn)槲覀冋靡褂茫藭r(shí)我們就可以用的服務(wù)來(lái)監(jiān)聽(tīng)了當(dāng)然,我們不能忘了清空訂閱最后一步就是在有返回的時(shí)候調(diào)用表單的現(xiàn)在我們可以在組件里顯示提醒了
原文:Connect Angular Forms to @ngrx/store
這篇文章中,我們將要討論如何用ngrx/effects連接Angular表單和ngrx/store
我們最終的結(jié)果是這樣的
ew-story0.component.ts @Component({ selector: "new-story-form", template: `
方便起見(jiàn),我們會(huì)寫一個(gè)簡(jiǎn)單的reducer來(lái)組織管理我們應(yīng)用里的所有的表單
狀態(tài)(the state)將由一個(gè)用ID作為key,表格數(shù)據(jù)作為value的簡(jiǎn)單對(duì)象構(gòu)成
舉個(gè)例子
connect-form.reducer.ts const initialState = { newStory: { title: "", description: "" }, contactUs: { email: "", message: "" } } export function forms(state = initialState, action) { }
我們先構(gòu)建一個(gè)action——UPDATE_FORM。這個(gè)action由兩個(gè)key:path和value組成
connect-form1.reducer.ts store.dispatch({ type: UPDATE_FORM, payload: { path: "newStory", value: formValue } });
然后這個(gè)reducer將負(fù)責(zé)更新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實(shí)例然后從store里更新表單數(shù)據(jù)
更新State當(dāng)表單數(shù)據(jù)改變時(shí)我們也需要更新表單狀態(tài)。我們可以通過(guò)訂閱(subscribe)這個(gè)valueChanges的可觀察對(duì)象(observable)然后調(diào)度(dispatch)這個(gè)UPDATE_FORM的action來(lái)獲取值
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同步所要做的全部工作了
通知和重置有兩件事我們要在這個(gè)部分完成
基于HTTP響應(yīng)返回來(lái)顯示通知給用戶——我們需要保證通知直接傳給組件并且不儲(chǔ)存信息在store里
有兩點(diǎn)原因
通常,沒(méi)有其他的組件需要這個(gè)信息
我們不想每次都重置store
當(dāng)提交成功時(shí)重置表單
我們將讓Angular盡其所能,處理好前端表單校驗(yàn)并重置表單
成功的Action成功的Action包含表單的path屬性所以我們可以知道到底哪個(gè)表單需要重置,同時(shí)什么時(shí)候需要去使用(emit)這個(gè)成功的事件
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一樣,因?yàn)橛衟ath的存在,我們也知道何時(shí)去使用(emit)錯(cuò)誤異常 的事件
connect-form3.directive.ts export const formErrorAction = ( path, error ) => ({ type: FORM_SUBMIT_ERROR, payload: { path, error } });
我們需要?jiǎng)?chuàng)建 成功 和 錯(cuò)誤異常 的輸出 然后 監(jiān)聽(tīng) FORM_SUBMIT_ERROR 和 FORM_SUBMIT_SUCCESS 的 action。
因?yàn)槲覀冋靡褂?ngrx/effects ,此時(shí)我們就可以用 Action 的服務(wù)(service)來(lái)監(jiān)聽(tīng)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)) } }
當(dāng)然,我們不能忘了清空訂閱
connect-form4.directive.ts ngOnDestroy() { this.formChange.unsubscribe(); this.formError.unsubscribe(); this.formSuccess.unsubscribe(); }
最后一步就是在有返回的時(shí)候調(diào)用表單的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)))) )
現(xiàn)在我們可以在組件里顯示提醒了
ew-story.component.ts @Component({ selector: "new-story-form", template: `
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/84215.html
摘要:來(lái)源于社區(qū),時(shí)至今日已經(jīng)基本成為的標(biāo)配了。部分很簡(jiǎn)單,要根據(jù)傳入的執(zhí)行不同的操作。當(dāng)性能遇到瓶頸時(shí)基本不會(huì)遇到,可以更改,保證傳入數(shù)據(jù)來(lái)提升性能。當(dāng)不再能滿足程序開(kāi)發(fā)的要求時(shí),可以嘗試使用進(jìn)行函數(shù)式編程。 Immutable & Redux in Angular Way 寫在前面 AngularJS 1.x版本作為上一代MVVM的框架取得了巨大的成功,現(xiàn)在一提到Angular,哪怕是已...
摘要:延伸閱讀學(xué)習(xí)與實(shí)踐資料索引與前端工程化實(shí)踐前端每周清單半年盤點(diǎn)之篇前端每周清單半年盤點(diǎn)之與篇前端每周清單半年盤點(diǎn)之篇 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開(kāi)發(fā)教程、工程實(shí)踐、深度閱讀、開(kāi)源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(hào)(ID:frontshow),及時(shí)獲取前端每周清單;本文則是對(duì)于半年來(lái)發(fā)布的前端每周清單...
摘要:目前電商領(lǐng)域有兩款比較出名的開(kāi)源電商網(wǎng)站解決方案,分別是基于開(kāi)發(fā)框架,代號(hào)為的開(kāi)源項(xiàng)目,以及基于的作為開(kāi)源項(xiàng)目的開(kāi)發(fā)成員之一,今天我想通過(guò)本文,給大家介紹一下我們平時(shí)購(gòu)物時(shí)最常使用到的功能之一,添加產(chǎn)品到購(gòu)物車的技術(shù)實(shí)現(xiàn)。 目前電商領(lǐng)域有兩款比較出名的開(kāi)源電商網(wǎng)站解決方案,分別是基于 Angular 開(kāi)發(fā)框架,...
摘要:首先,我們需要在入口頁(yè)面的中配置根路徑然后創(chuàng)建一個(gè)路由模塊路由配置在主模塊中導(dǎo)入配置好的路由模塊而在頁(yè)面中需要一個(gè)容器去承載上面代碼中的定義了用戶點(diǎn)擊后的路由跳轉(zhuǎn),定義該路由激活時(shí)的樣式類。 剛實(shí)習(xí)的時(shí)候用過(guò)AngularJS,那時(shí)候真的是連原生JavaScript都不會(huì)寫,依樣畫葫蘆做了幾個(gè)管理后臺(tái)。然后突然換項(xiàng)目了,AngularJS就不寫了,感覺(jué)前前后后接觸了一年多的Angula...
摘要:前端日?qǐng)?bào)精選精讀個(gè)最佳特性翻譯輕量級(jí)函數(shù)式編程第章組合函數(shù)之組件類型寫的姿勢(shì)中文周二放送面試題詳解知乎專欄譯原生值得學(xué)習(xí)嗎答案是肯定的掘金個(gè)超贊的視覺(jué)效果眾成翻譯布局時(shí)常見(jiàn)總結(jié)騰訊前端團(tuán)隊(duì)社區(qū)歸檔打地鼠入門學(xué)習(xí)書(shū)籍 2017-08-30 前端日?qǐng)?bào) 精選 精讀《Web fonts: when you need them, when you don’t》10個(gè)最佳ES6特性翻譯 -《Jav...
閱讀 3328·2023-04-25 16:25
閱讀 3856·2021-11-15 18:01
閱讀 1614·2021-09-10 11:21
閱讀 3021·2021-08-02 16:53
閱讀 3090·2019-08-30 15:55
閱讀 2496·2019-08-29 16:24
閱讀 2107·2019-08-29 13:14
閱讀 1039·2019-08-29 13:00