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

資訊專欄INFORMATION COLUMN

我理解的 core 目錄

callmewhy / 808人閱讀

摘要:只需引入一次的什么是項(xiàng)目中只需要引入一次的舉個(gè)例子,全局錯(cuò)誤處理根路由數(shù)據(jù)預(yù)加載請(qǐng)求攔截器等。更漂亮的是為我們提供了攔截器接口,我們只管開發(fā)攔截器邏輯功能,調(diào)用及使用全部控制權(quán)都在框架內(nèi)。

...

過了一遍 Angular 文檔 的小伙伴大致都會(huì)記得最佳實(shí)踐中提到過的有關(guān)CoreModule的一些解釋和說明,其實(shí)關(guān)于名字的命名不是強(qiáng)制性的,只要團(tuán)隊(duì)中一致 pass,你把它命名為XXXModule都無所謂。但是最主要的,還是我們需要理解“core”的作用以及在項(xiàng)目中發(fā)揮更好的作用和地位。

我記錄下我項(xiàng)目中對(duì)“core”的一些拙略見解和搭配。

core目錄

縱觀整個(gè)Angular項(xiàng)目結(jié)構(gòu)以及最佳實(shí)踐,我們通常把項(xiàng)目按功能劃分文件夾,比如工具、共享、全局核心、頁(yè)面模塊組件、公用模塊組件等等,“core”在這里相當(dāng)于全局核心類型的范圍,那全局核心類型到底是聚集了項(xiàng)目的哪些功能呢?我的理解是我們可以把 全局單例服務(wù)、只需要引入一次 的東西都?xì)w并到這里。

全局單例服務(wù):這些服務(wù)在整個(gè)應(yīng)用生命周期內(nèi)只存在一個(gè)實(shí)例,也就是數(shù)據(jù)是全局互通的,而在 Angular 中實(shí)現(xiàn)單例服務(wù)就需要一個(gè)中間提供商(module)來做中介,也就是所謂的“CoreModule”,然后在根模塊引用一次便可全局使用,這也是官方推薦的一種單例服務(wù)做法。然而在 Angular 6 + 版本后,官方為 Injectable 裝飾器提供了 providedIn: "root" 的選項(xiàng),讓聲明的服務(wù)直接成為單例服務(wù),此后再不用通過“CoreModule”來提供服務(wù),但是我們的單例服務(wù)仍然可以放在 core目錄 中,通過 路徑別名 配置來直接訪問服務(wù),因?yàn)閷?shí)際上,單例服務(wù)只會(huì)乖乖在 core目錄中 ,不會(huì)再有其他東西來干擾。

只需引入一次的?:什么是項(xiàng)目中只需要引入一次的?舉個(gè)例子,全局錯(cuò)誤處理、根路由數(shù)據(jù)預(yù)加載、http請(qǐng)求攔截器等。這些都是通過一次配置就能一直用到老的東西,而且不可能會(huì)有其他兄弟來直接使用的東西,順理成章就需要?dú)w并到 core目錄 中,并且有的需要被“CoreModule”引用,有的需要被“AppModule”引用。

我列舉來幾個(gè)更加詳細(xì)的例子來說說這些類別:

應(yīng)用初始數(shù)據(jù)加載

在開發(fā)單頁(yè)應(yīng)用特別是管理系統(tǒng)的時(shí)候,可能項(xiàng)目的構(gòu)成除了中心主系統(tǒng)還衍生了很多個(gè)子項(xiàng)目系統(tǒng),這種情況下登錄授權(quán)一般都是在主系統(tǒng)完成,然后前后端通過單點(diǎn)登錄確保子系統(tǒng)能使用。這時(shí)子系統(tǒng)一般都是一個(gè)新的項(xiàng)目,我們都知道 Angular 提供了強(qiáng)大的路由功能,可以通過路由守衛(wèi)來預(yù)加載系統(tǒng),然而我們需要的授權(quán)信息是相對(duì)整個(gè)應(yīng)用而不是某個(gè)路由而言的,那這個(gè)時(shí)候我們就需要一個(gè)根級(jí)別的數(shù)據(jù)預(yù)加載功能來完成授權(quán)等功能。

Angular 還是幫你開辟好了入口,這時(shí)我們只需要一個(gè)APP_INITIALIZER就可以完成預(yù)加載。前提是我們定義好了預(yù)加載的數(shù)據(jù)操作邏輯,舉個(gè)例子:

/**
 * app 初始化前身份驗(yàn)證操作
 */
@Injectable({
    providedIn: "root"
})
export class AppInitAuthService {
    constructor(
        ...,
        private userInfoService: UserInfoService,
    ) { }

    /** 驗(yàn)證當(dāng)前token身份 */
    tokenAuth(): Promise {
        return new Promise((resolve,reject) => {
            return this.userInfoService.getUserInfoServer().subscribe(res => {
                if(res.reasonCode == "notLoggedIn"){
                    //未登錄 
                    //可以進(jìn)行取消授權(quán)處理
                    ...
                }else{
                    //獲取了授權(quán)數(shù)據(jù),todo ...
                    resolve(true)
                }
            })
        })
     }
}

此處聲明了一個(gè)基本的用戶授權(quán)信息獲取服務(wù),接下來我們可以直接通過APP_INITIALIZER來完成數(shù)據(jù)預(yù)加載功能,只需要在 CoreModule 中聲明剛才提供的處理服務(wù),Angular 會(huì)自動(dòng)在根組件初始化前查詢并執(zhí)行 APP_INITIALIZER 所注入的所有服務(wù)函數(shù),由于我們提供的是一個(gè) Promise 對(duì)象,所以 Angular 會(huì)等待執(zhí)行結(jié)果:

@NgModule({
    ...
    providers: [
        ...
        {
            provide: APP_INITIALIZER,
            multi: true,
            useFactory: (appInit: AppInitAuthService) => {
                return () => appInit.tokenAuth()
            },
            deps: [AppInitAuthService]
        }
    ]
})
export class CoreModule {
    constructor(
        ...
    ) {}
}

只要AppModule引用了CoreModule,項(xiàng)目會(huì)自動(dòng)完成預(yù)授權(quán)處理功能,完全無需其他組件摻入。

全局錯(cuò)誤處理

有時(shí)候我們需要全局錯(cuò)誤處理機(jī)制。比如我們編譯更新了項(xiàng)目版本,多個(gè)某個(gè)模塊功能,但是用戶這邊并沒有去實(shí)時(shí)刷新,當(dāng)意外去到某個(gè)原本不存在的路由時(shí) Angular 會(huì)捕獲到找不到模塊的錯(cuò)誤,這是我們就可以提前在錯(cuò)誤處理中去對(duì)用戶進(jìn)行較友好的提示等等;又比如我們會(huì)想要去接入前端監(jiān)控平臺(tái)像 fundebug 等等,具體對(duì)實(shí)現(xiàn)方式也是一樣通過 Angular 提供的捕錯(cuò)功能來實(shí)現(xiàn)。

一個(gè)最簡(jiǎn)單的錯(cuò)誤處理服務(wù)如下:

import { ErrorHandler } from "@angular/core"

export class HandleCommon extends ErrorHandler{
    constructor(){
        super()
    }

    handleError(error: Error){
        //注意調(diào)基類處理函數(shù),不然會(huì)覆蓋默認(rèn)行為,比如控制臺(tái)不會(huì)看到報(bào)錯(cuò)
        super.handleError(error)
        if (/Loading chunk [d]+ failed/.test(error.message)) {
            //捕獲找不到模塊 (服務(wù)端目錄數(shù)據(jù)變動(dòng))
            ...
        } 
        //... 各種錯(cuò)誤處理    
    }
}

然后我們直接在AppModule中聲明一個(gè) ErrorHandler 令牌對(duì)應(yīng)的服務(wù),就可以實(shí)現(xiàn)全局錯(cuò)誤監(jiān)聽處理:

import { NgModule, ErrorHandler } from "@angular/core"
import { HandleCommon } from "../core"

@NgModule({
    ...
    providers: [
        ...
        {
            provide: ErrorHandler,
            useFactory: () => {
                return new HandleCommon()
            }
        }
    ],
    bootstrap: [
        AppComponent
    ]
})
export class AppModule { }
http請(qǐng)求攔截器

盡管 Angular 提供了十分漂亮的 HttpClient 給開發(fā)者舒服地進(jìn)行網(wǎng)絡(luò)請(qǐng)求操作,但是有很多針對(duì)網(wǎng)絡(luò)請(qǐng)求的需求需要我們自己去開發(fā),像 http 超時(shí)攔截、token 攔截、錯(cuò)誤處理攔截等等,這些也都屬于一次引用,全局使用的范疇。更漂亮的是 Angular 為我們提供了攔截器接口,我們只管開發(fā)攔截器邏輯功能,調(diào)用及使用全部控制權(quán)都在框架內(nèi)。由于攔截器涉及比較多東西,這里放一個(gè)最為簡(jiǎn)單的實(shí)現(xiàn)如下:

import {
    HttpInterceptor,
    HttpRequest,
    HttpHandler,
    HttpEvent
} from "@angular/common/http"
import { Injectable } from "@angular/core"
import { Observable } from "rxjs"
import { tap } from "rxjs/operators"

//攔截器 - 添加請(qǐng)求頭
@Injectable()
export class TokenInterceptor implements HttpInterceptor {

    constructor() { }

    intercept(req: HttpRequest, next: HttpHandler): Observable> {
        //通過某些邏輯獲取 token
        let token = "xxxx"
        if (token) {
            token = `Bearer ${token}`
            req = req.clone({
                setHeaders: {
                    Authorization: token
                }
            })
        }
        return next.handle(req)
    }
}

只需要在 CoreModule 中通過 HTTP_INTERCEPTORS 令牌來聲明我們寫好的攔截器,框架會(huì)在正確的時(shí)機(jī)自動(dòng)處理和調(diào)用攔截器邏輯:

@NgModule({
    providers: [
        ...,
        {
            provide: HTTP_INTERCEPTORS,
            useClass: TokenInterceptor,
            //必須設(shè)置,攔截器是個(gè)數(shù)組集合而不僅僅只有一個(gè)
            multi: true
        }
    ]
})
export class CoreModule {
    constructor() {}
}
一些單例服務(wù)等等

應(yīng)用中或多或少有一些需要在全局流通的數(shù)據(jù),比如全局的用戶信息管理:

@Injectable({
    providedIn: "root"
})
export class UserInfoService {
    //用戶數(shù)據(jù) 全局共享 數(shù)據(jù)流
    userInfo$: BehaviorSubject = new BehaviorSubject(null)

    constructor() { }

    /**
     * 獲取用戶數(shù)據(jù)
     */
    getUserInfoServer(): Observable {
        ...
    }

    /**
     * 退出登錄
     */
    getUserLogoutServer(): Observable {
        ...
    }
}

作為頻繁被存取的介質(zhì),單例模式自然而然是它的特點(diǎn),所以最好也一起歸并到所謂的 core目錄 中。

因人而異

前面列舉了一些常用的類別來說明 core目錄 以及 “CoreModule” 存在的意義。除了一些需要“CoreModule”來作為橋梁的例子,貌似 core目錄 并不是必須要存放某些東西的,比如全局的單例對(duì)象就完全可以多帶帶使用其他的文件夾來存放維護(hù)。是對(duì)的,沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn)來約束我們到底是要去如何組織代碼目錄結(jié)構(gòu),所有項(xiàng)目都是因人而異,自己覺得舒服的、可維護(hù)的才最重要。

本記錄只是為了更加貼近官方最佳實(shí)踐而如此組織,純粹作為一個(gè)記錄以及給大家的一個(gè)參考。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/102477.html

相關(guān)文章

  • 【小項(xiàng)目】全棧開發(fā)培訓(xùn)手冊(cè) | 后端(1) vert.x框架理解

    摘要:二來,給大家新開坑的項(xiàng)目一個(gè)參考。因此,本系列以主要以官方文檔為基礎(chǔ),將盡可能多的特性融入本項(xiàng)目,并標(biāo)注官網(wǎng)原文出處,有興趣的小伙伴可點(diǎn)擊深入了解。可以通過一些特殊協(xié)議例如將消息作為統(tǒng)一消息服務(wù)導(dǎo)出。下載完成后自行修改和。 開坑前言 我給這個(gè)專欄的名氣取名叫做小項(xiàng)目,聽名字就知道,這個(gè)專題最終的目的是帶領(lǐng)大家完成一個(gè)項(xiàng)目。為什么要開這么大一個(gè)坑呢,一來,雖然網(wǎng)上講IT知識(shí)點(diǎn)的書籍鋪天蓋...

    hightopo 評(píng)論0 收藏0
  • Angular系列學(xué)習(xí)一:使用Angujar CLI快速理解Angular項(xiàng)目一些基本概念和寫法

    摘要:開始項(xiàng)目前,你需要先安裝和,然后執(zhí)行安裝。一用命令行新建一個(gè)項(xiàng)目執(zhí)行上面的命令就會(huì)自動(dòng)新建一個(gè)項(xiàng)目,并啟動(dòng)了項(xiàng)目。 作者:心葉時(shí)間:2018-04-22 09:13 Angular CLI是一個(gè)命令行界面工具,它可以創(chuàng)建項(xiàng)目、添加文件以及執(zhí)行一大堆開發(fā)任務(wù),比如測(cè)試、打包和發(fā)布,這里的快速開始就是基于這個(gè)命令。 開始項(xiàng)目前,你需要先安裝node和npm,然后執(zhí)行npm install ...

    trilever 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<