前情提要 其實也不算是初體驗啦 因為之前就有把promise的程式改成用rx,但那時候還是非常不了解
最近在跟人一起寫angular的workshop,飲料維護及訂購的功能 就開始用一些之前沒用到的功能rx、form control等…
嗯~還是不要太多廢話XD
從promise改成rx 從ng1的時候,就都是寫promise,所以剛轉到二的時候,看到官網寫rx,就沒有想要去寫他o.0(年少不懂事… 一開始的promise
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 getStepListByProjectId (id: number ) { return this ._http .post (this .url + "GetStepListByProjectId" , { projectId : id }) .toPromise () .then (res => { var data = res.json (); if (data.Result ) { data.StepList = this .parseStepDataList (data.StepList ); if (data.StepList .length > 0 ) { data.StepList [0 ].SelectedFlag = true ; } return data; }) .catch (this .handleError ); }
改寫成rx後,在重新整理過,是不是感覺更精簡了 但這時候其實還沒什麼感覺,因為比較算是轉換而已,對於rx還是很不熟…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 getStepListByProjectId (id: number ) { return this ._http .post (this .url + "GetStepListByProjectId" , { projectId : id }) .switchMap (this .checkResult ) .map (this .parseStepDataList ) .catch (this .handleError ); } private checkResult (res : any ): Observable <any > { var data = res.json (); if (!data.Result ) { Observable .throw (data.ErrorMessage ); } return Observable .of (data.StepList ); }
rx進一步的應用 concatMap、toArray 這次的需求是這樣的,從api取得的資料中,沒有其中一個物件中的欄位state 所以我要把取得的資料重新assign欄位值
這樣的寫法其實已經可以達到我的需求,但總覺得不是很好看 這是第一版
1 2 3 4 5 6 7 8 9 getBeverageList (): Observable <BeverageData []> { return this ._http .get (this .beverageAPI , this .options ) .map (response => response.json () as BeverageData []) .map (item => item.map (p => { p.state = StateType .None ; return p; })) .catch (this .handleError ); }
剛好kevin介紹了一個工具Quokka.js ,可以不用console.log就可以把結果呈現在旁邊 於是就開始實驗怎麼寫,可以讓這段更好看 先把陣列拆開,做完以後再組合起來,這樣的寫法看起來是不是更清楚一點 這是第二版
1 2 3 4 5 6 7 8 9 10 11 12 getBeverageList (): Observable <BeverageData []> { return this ._http .get (this .beverageAPI , this .options ) .map (response => response.json () as BeverageData []) .concatMap (p => p) .map (p => { p.state = StateType .None ; return p; }) .toArray () .catch (this .handleError ); }
mergeMap post資料回server端後,想要重新取得全部的資料,這時候又不希望由前面再次呼叫 這時候可以直接在service層一次做完
那因為是呼叫另一個已經寫好的service,所以必須要把自己的observable和另一個接起來 這時候我們要使用到mergeMap
1 2 3 4 5 postBeverage (index :number , beverage : BeverageData ):Observable <BeverageData []> { return this ._http .post (this .beverageAPI + "/" + index, beverage, this .options ) .mergeMap (resp => this .getBeverageList ()) .catch (this .handleError ); }
後續 rx這東西真的要有案例來學,才有辦法體會他的奧妙,不然看文件看多了還是不太清楚如何搭配使用