国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從命令式到響應式(六)

sanyang / 1651人閱讀

摘要:從這個系列的第一章開始到第五章,基于的響應式編程的基礎知識基本上就介紹完了,當然有很多知識點沒有提到,比如,等,不是他們不重要,而是礙于時間精力等原因沒辦法一一詳細介紹。

從這個系列的第一章開始到第五章,基于rxjs的響應式編程的基礎知識基本上就介紹完了,當然有很多知識點沒有提到,比如 Scheduler, behaviorSubject,replaySubject等,不是他們不重要,而是礙于時間、精力等原因沒辦法一一詳細介紹。從這章開始將把響應式放在angular的大環境中,看如何在實際項目中去使用,當然這些都是個人在使用中的一些經驗,如有不妥,歡迎指正。

另外本章開始的示例代碼可能只是一些片段,或思路,正式要跑起來需要各位自己將代碼放入正確的環境中。

angular中響應式接口無處不在

既然 angular 中內置了rxjs,必須有好多地方都能找到響應式的影子,客官請看:

ActivatedRoute - 經常用它來獲取路由上的信息,比如傳遞的參數等。

export interface ActivatedRoute {
    url: Observable
    params: Observable;
    queryParams: Observable;
    fragment: Observable;
    data: Observable;
    get paramMap: Observable;
    get queryParamMap: Observable;
    toString(): string;
}

AbstractControl - FormControl的基類,尤其響應式表單中,你一定見過它。

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 - 組件向外傳遞數據時,你一定用過吧?

export class EventEmitter extends Subject {
    subscribe(generatorOrNext?: any, error?: any, complete?: any): any;
}

沒有發現Observable?仔細看,它繼承自Subject,那Subject呢?接著看:

export declare class Subject extends Observable implements ISubscription {
    ...省略
}

Subject 最終還得繼承自 Observable。當然還有很多其它的,總而言之請記住響應式的世界里everything is Observable,不管是輸入還是輸出。

搭建響應式的組件

輸入和輸出是編程中兩個無處不在的東西,只要涉及到交互的東西,都可以把它抽象成輸入和輸出。

最明顯的,當我們使用 @Input 和 @Output 無疑是在和輸入和輸出打交道,除此之外呢。如果我們把定義component的 Class看作一部分,那么它給template 傳遞的數據也可以認為是一種輸出,而它從各service獲取的數據也可以當作一種數據輸入。基于這種想法,我們可以認為一個組件就是連接數據和模板的橋梁,它最主要的功能就是獲取服務中的數據作為輸入輸出給模板,當然也可以獲取模板中產生的數據作為輸入輸出給服務。于是我們可以抽象出這樣一個組件:

export abstract class BaseComponent {

    abstract subscription$$: Subscription; // 用于在組件銷毀時取消不得不手動訂閱的一些流。

    abstract launch(option?: any): void;  // 給服務輸出數據

    abstract initialModel(option?: any): void; // 從服務中獲取數據輸入
}

initialModel 所有組件中要用到的數據都在這個方法中獲得,再分發給數據的使用者。

launch 所有組件中需要向服務傳遞的數據都會在這個方法中向外傳遞。

subscription$$ 在實際項目中,無法避免會手動訂閱一些流,其中的某一些流可能需要我們手動釋放,這個變量可以全權負責,而且它的初始化基本上會被固定在 launch 方法中。

假設我們需要實現一個帶有圖片驗證碼的登錄功能,我們來實現它的數據交互。

@Component({
    ...
})
export class LoginComponent extends BaseComponent implements OnInit, OnDestroy {
    subscription$$: Subscription;

    randomCode: Observable; // 隨機碼,在頁面上展示給用戶

    generateCode$: Subject = new Subject(); // 和服務交互,通知服務我們需要一個隨機碼。

    // 這里我們沒有定義這個接口,你可以想像它就是登錄表單的值,例如: { username: string; password: string; randomCode: string}; 它的功能就是發出登錄請求的數據。
    login$: Subject = new Subject();

    constructor(private auth: AuthService) { } // 這個服務隨后實現

    ngOnInit() {
        this.initialModel();

        this.launch();

        this.goTo(); // 初始化時就調用跳轉函數。
    }

    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 => {
                // 跳轉邏輯等等。
            })
        )
    }

    ngOnDestroy {
        this.subscription$$.unsubscribe();
    }
}

通過閱讀以上代碼,我們的核心關注點只需要放在 initialModel 和 launch 兩個方法上,一個告訴我們獲取了哪些數據,一個告訴我們輸出了哪此數據。另外你會發現,登錄動作和獲取驗證碼的動作在組件初始化時就已經告訴了服務,這種命令式的是完全不同的兩種風格,在命令式的風格中我們都是在等到用戶點擊登錄按鈕時才去調用login函數,發起登錄動作。下面來看服務代碼:

@Injectable()
export class AuthService {

    login$: BehaviorSubject = new BehaviorSubject();

    constructor(private http: Http) { }

    login(data: Observable): Subscription {
        // url: 請求的url; Response: angular 定義的http響應接口。
        return this.http.post(url)
                .map((res: Response) => {
                // 假設登錄成功會后臺會返回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) => {
                // 假設數據保存在random 字段下
                const body = res.json();

                return body.data.random;
            });
    }

    isLoginSuccess(): Observable {
        return this.login$.mapTo(true);
    }
}

基于開始說到的思路,我們基本搭建好了一個完全基于響應式風格的登錄組件的骨架,可以說基本的套路出來了,暫時先到這里。各位可以先想一下可以擴展哪些功能,比如實現30秒換一次驗證碼,用戶點擊時立即更換驗證碼等,下次繼續。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97260.html

相關文章

  • Spring Boot 2 快速教程:WebFlux 快速入門(二)

    摘要:響應式編程是基于異步和事件驅動的非阻塞程序,只是垂直通過在內啟動少量線程擴展,而不是水平通過集群擴展。三特性常用的生產的特性如下響應式編程模型適用性內嵌容器組件還有對日志消息測試及擴展等支持。 摘要: 原創出處 https://www.bysocket.com 「公眾號:泥瓦匠BYSocket 」歡迎關注和轉載,保留摘要,謝謝! 02:WebFlux 快速入門實踐 文章工程: JDK...

    gaara 評論0 收藏0
  • vue組件間通信種方(完整版)

    摘要:本文總結了組件間通信的幾種方式,如和,以通俗易懂的實例講述這其中的差別及使用場景,希望對小伙伴有些許幫助。狀態改變提交操作方法。 前言 組件是 vue.js最強大的功能之一,而組件實例的作用域是相互獨立的,這就意味著不同組件之間的數據無法相互引用。一般來說,組件可以有以下幾種關系:showImg(https://segmentfault.com/img/remote/146000001...

    frontoldman 評論0 收藏0
  • 關于Vue2一些值得推薦的文章 -- 五、月份

    摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...

    sutaking 評論0 收藏0
  • 關于Vue2一些值得推薦的文章 -- 五、月份

    摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...

    khs1994 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<