摘要:從這個系列的第一章開始到第五章,基于的響應(yīng)式編程的基礎(chǔ)知識基本上就介紹完了,當(dāng)然有很多知識點(diǎn)沒有提到,比如,等,不是他們不重要,而是礙于時間精力等原因沒辦法一一詳細(xì)介紹。
從這個系列的第一章開始到第五章,基于rxjs的響應(yīng)式編程的基礎(chǔ)知識基本上就介紹完了,當(dāng)然有很多知識點(diǎn)沒有提到,比如 Scheduler, behaviorSubject,replaySubject等,不是他們不重要,而是礙于時間、精力等原因沒辦法一一詳細(xì)介紹。從這章開始將把響應(yīng)式放在angular的大環(huán)境中,看如何在實際項目中去使用,當(dāng)然這些都是個人在使用中的一些經(jīng)驗,如有不妥,歡迎指正。
另外本章開始的示例代碼可能只是一些片段,或思路,正式要跑起來需要各位自己將代碼放入正確的環(huán)境中。
angular中響應(yīng)式接口無處不在既然 angular 中內(nèi)置了rxjs,必須有好多地方都能找到響應(yīng)式的影子,客官請看:
ActivatedRoute - 經(jīng)常用它來獲取路由上的信息,比如傳遞的參數(shù)等。
export interface ActivatedRoute { url: Observableparams: Observable ; queryParams: Observable ; fragment: Observable ; data: Observable; get paramMap: Observable ; get queryParamMap: Observable ; toString(): string; }
AbstractControl - FormControl的基類,尤其響應(yīng)式表單中,你一定見過它。
export abstract class AbstractControl { get valueChanges: Observable; get statusChanges: Observable ; }
Http - 這個更不用說,使用Http通信的項目離了它簡直了沒法干活。
export class Http { get(url: string, options?: RequestOptionsArgs): Observable; post(url: string, body: any, options?: RequestOptionsArgs): Observable ; head(url: string, options?: RequestOptionsArgs): Observable ; }
EventEmitter - 組件向外傳遞數(shù)據(jù)時,你一定用過吧?
export class EventEmitterextends Subject { subscribe(generatorOrNext?: any, error?: any, complete?: any): any; }
沒有發(fā)現(xiàn)Observable?仔細(xì)看,它繼承自Subject,那Subject呢?接著看:
export declare class Subjectextends Observable implements ISubscription { ...省略 }
Subject 最終還得繼承自 Observable。當(dāng)然還有很多其它的,總而言之請記住響應(yīng)式的世界里everything is Observable,不管是輸入還是輸出。
搭建響應(yīng)式的組件輸入和輸出是編程中兩個無處不在的東西,只要涉及到交互的東西,都可以把它抽象成輸入和輸出。
最明顯的,當(dāng)我們使用 @Input 和 @Output 無疑是在和輸入和輸出打交道,除此之外呢。如果我們把定義component的 Class看作一部分,那么它給template 傳遞的數(shù)據(jù)也可以認(rèn)為是一種輸出,而它從各service獲取的數(shù)據(jù)也可以當(dāng)作一種數(shù)據(jù)輸入?;谶@種想法,我們可以認(rèn)為一個組件就是連接數(shù)據(jù)和模板的橋梁,它最主要的功能就是獲取服務(wù)中的數(shù)據(jù)作為輸入輸出給模板,當(dāng)然也可以獲取模板中產(chǎn)生的數(shù)據(jù)作為輸入輸出給服務(wù)。于是我們可以抽象出這樣一個組件:
export abstract class BaseComponent { abstract subscription$$: Subscription; // 用于在組件銷毀時取消不得不手動訂閱的一些流。 abstract launch(option?: any): void; // 給服務(wù)輸出數(shù)據(jù) abstract initialModel(option?: any): void; // 從服務(wù)中獲取數(shù)據(jù)輸入 }
initialModel 所有組件中要用到的數(shù)據(jù)都在這個方法中獲得,再分發(fā)給數(shù)據(jù)的使用者。
launch 所有組件中需要向服務(wù)傳遞的數(shù)據(jù)都會在這個方法中向外傳遞。
subscription$$ 在實際項目中,無法避免會手動訂閱一些流,其中的某一些流可能需要我們手動釋放,這個變量可以全權(quán)負(fù)責(zé),而且它的初始化基本上會被固定在 launch 方法中。
假設(shè)我們需要實現(xiàn)一個帶有圖片驗證碼的登錄功能,我們來實現(xiàn)它的數(shù)據(jù)交互。
@Component({ ... }) export class LoginComponent extends BaseComponent implements OnInit, OnDestroy { subscription$$: Subscription; randomCode: Observable; // 隨機(jī)碼,在頁面上展示給用戶 generateCode$: Subject = new Subject(); // 和服務(wù)交互,通知服務(wù)我們需要一個隨機(jī)碼。 // 這里我們沒有定義這個接口,你可以想像它就是登錄表單的值,例如: { username: string; password: string; randomCode: string}; 它的功能就是發(fā)出登錄請求的數(shù)據(jù)。 login$: Subject = new Subject(); constructor(private auth: AuthService) { } // 這個服務(wù)隨后實現(xiàn) ngOnInit() { this.initialModel(); this.launch(); this.goTo(); // 初始化時就調(diào)用跳轉(zhuǎn)函數(shù)。 } initialModel() { this.randomCode = this.auth.getRandomCode(); } launch() { this.subscription = this.auth.login(this.login$) .add(this.auth.generateRandomCode(this.generateCode$)); } goTo() { this.subscription.add( this.auth.isLoginSuccess().subscribe(success => { // 跳轉(zhuǎn)邏輯等等。 }) ) } ngOnDestroy { this.subscription$$.unsubscribe(); } }
通過閱讀以上代碼,我們的核心關(guān)注點(diǎn)只需要放在 initialModel 和 launch 兩個方法上,一個告訴我們獲取了哪些數(shù)據(jù),一個告訴我們輸出了哪此數(shù)據(jù)。另外你會發(fā)現(xiàn),登錄動作和獲取驗證碼的動作在組件初始化時就已經(jīng)告訴了服務(wù),這種命令式的是完全不同的兩種風(fēng)格,在命令式的風(fēng)格中我們都是在等到用戶點(diǎn)擊登錄按鈕時才去調(diào)用login函數(shù),發(fā)起登錄動作。下面來看服務(wù)代碼:
@Injectable() export class AuthService { login$: BehaviorSubject = new BehaviorSubject(); constructor(private http: Http) { } login(data: Observable): Subscription { // url: 請求的url; Response: angular 定義的http響應(yīng)接口。 return this.http.post(url) .map((res: Response) => { // 假設(shè)登錄成功會后臺會返回token,這里我們利用 BehaviorSubject 來保存這個 token; const body = res.json(); return body.data.token; }) .subscribe(this.login$); } generateRandomCode(signal: Observable ): Observable { return this.http.get(url) .map((res: Response) => { // 假設(shè)數(shù)據(jù)保存在random 字段下 const body = res.json(); return body.data.random; }); } isLoginSuccess(): Observable { return this.login$.mapTo(true); } }
基于開始說到的思路,我們基本搭建好了一個完全基于響應(yīng)式風(fēng)格的登錄組件的骨架,可以說基本的套路出來了,暫時先到這里。各位可以先想一下可以擴(kuò)展哪些功能,比如實現(xiàn)30秒換一次驗證碼,用戶點(diǎn)擊時立即更換驗證碼等,下次繼續(xù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/97260.html
摘要:響應(yīng)式編程是基于異步和事件驅(qū)動的非阻塞程序,只是垂直通過在內(nèi)啟動少量線程擴(kuò)展,而不是水平通過集群擴(kuò)展。三特性常用的生產(chǎn)的特性如下響應(yīng)式編程模型適用性內(nèi)嵌容器組件還有對日志消息測試及擴(kuò)展等支持。 摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號:泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載,保留摘要,謝謝! 02:WebFlux 快速入門實踐 文章工程: JDK...
摘要:本文總結(jié)了組件間通信的幾種方式,如和,以通俗易懂的實例講述這其中的差別及使用場景,希望對小伙伴有些許幫助。狀態(tài)改變提交操作方法。 前言 組件是 vue.js最強(qiáng)大的功能之一,而組件實例的作用域是相互獨(dú)立的,這就意味著不同組件之間的數(shù)據(jù)無法相互引用。一般來說,組件可以有以下幾種關(guān)系:showImg(https://segmentfault.com/img/remote/146000001...
摘要:五六月份推薦集合查看最新的請點(diǎn)擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點(diǎn)擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
閱讀 3708·2021-11-24 10:22
閱讀 3780·2021-11-22 09:34
閱讀 2654·2021-11-15 11:39
閱讀 1584·2021-10-14 09:42
閱讀 3714·2021-10-08 10:04
閱讀 1617·2019-08-30 15:52
閱讀 921·2019-08-30 13:49
閱讀 3079·2019-08-30 11:21