Categories
程式開發

Angular應用”老手“也未必掌握的十大實用特性


如果你已經是編寫Angular應用的”老手“,可能會覺得這篇文章介紹的這些特性自己肯定都很熟悉。但事實未必如此,不信的話等你看完再說。

1. Title

Title標籤是一個HTML元素,用於指定網頁標題。 Title標籤作為給定結果的可點擊標題,顯示在搜索引擎結果頁面(SERP)上。它們對於可用性、SEO和社交共享而言至關重要。

Angular應用使用index.html中的,在瀏覽器窗口中設置標題。導航到Angular中的組件不會更改標題。

那麼你知道嗎,其實可以通過組件來設置瀏覽器標題。

Angular在@angular/platform-b​​rowser中有一個Title服務。我們只需將Title服務注入到組件中,並使用setTitle方法設置標題即可。

import { Title } from "@angular/platform-browser"
@Component({
    ...
})
export class LoginComponent implements OnInit {
    constructor(private title: Title) {}
    ngOnInit() {
        title.setTitle("Login")
    }
}

當我們導航到LoginComponent時,瀏覽器的標題將設置為“Login”。

我們可以在項目的所有組件中重複這一操作,這樣在導航到它們的位置時,瀏覽器窗口將更改為組件設置的標題。

2. Meta

我們的Angular應用渲染的內容大部分來自於index.html。我們的應用會擁有在index.html中設置的一個meta標籤。 Angular在@angular/platform-b​​rowser中有一個Meta服務,使我們能夠從組件中設置meta標籤。

這是很有用的功能,可以更好地進行搜索引擎優化(SEO),也可以將組件擁有的頁面共享給社交媒體。

根據維基百科的定義:

Meta是HTML和XHTML文檔中使用的標籤,用於提供網頁的結構化元數據。它們是網頁head的一部分,可以在同一頁面上使用具有不同屬性的多個Meta元素。 Meta元素可用於指定頁面描述、關鍵字,以及其他head元素和屬性未提供的元數據。

Meta元素提供有關網頁的信息,搜索引擎可以在這些信息的幫助下正確地分類網頁。

它用起來非常容易,只需從@angular/platform-b​​rowser導入Meta,並將其註入到我們的組件中即可。

import { Meta } from "@angular/platform-browser"
@Component({
    ...
})
export class BlogComponent implements OnInit {
    constructor(private meta: Meta) {}
    ngOnInit() {
        meta.updateTag({name: "title", content: ""})
        meta.updateTag({name: "description", content: "Lorem ipsum dolor"})
        meta.updateTag({name: "image", content: "./assets/blog-image.jpg"})
        meta.updateTag({name: "site", content: "My Site"})
    }
}

有了它,我們的BlogComponent可以渲染在Facebook和Twitter等網頁上,並帶有我們組件的描述信息,提供標題、圖像和註釋。

這個你也聽過嗎?

3. 覆蓋模板插值

我們都在模板中使用默認模板插值器{{}}來顯示組件中的屬性。

開頭為{{,結尾為}}。如果我們在它們之間放置一個屬性成員,它將渲染在瀏覽器DOM上。

你知道我們可以用自己的符號覆蓋默認的封裝開始和結束定界符嗎?很簡單,在Component裝飾器的interpolation屬性中指定即可。

@Component({
    interpolation: ("((","))")
})
export class AppComponent {

AppComponent模板中使用的插值將不再是“{{}}”,而是“(())”。

@Component({
    template: `
        
((data))
`, interpolation: ("((","))") }) export class AppComponent { data: any = "dataVar" }

在渲染時,將渲染“dataVar”以代替((data))。

4. Location

我們可以使用Location服務獲取當前瀏覽器窗口的URL。根據所使用的LocationStrategy,Location將存儲URL的路徑或URL的哈希段。

有了Location,我們可以轉到一個URL,在平台的歷史記錄中向前或向後跳轉,更改瀏覽器URL,替換平台的歷史記錄棧中的頂部項等。

我們從CommonModule注入Location服務,就可以使用它了。

import { Location } from "@angular/common"
@Component({
    ...
})
export class AppComponent {
    constructor(private location: Location) {}
    navigatTo(url) {
        this.location.go(url)
    }
    goBack() {
        location.back()
    }
    goForward() {
        location.forward()
    }
}

5. DOCUMENT

有時我們想要獲取文檔模型,以便我們可以從Angular應用中執行DOM操作。

使用DOCUMENT就可以做到這一點。 DOCUMENT是表示主要渲染上下文的DI令牌。在瀏覽器中這就是DOM文檔。它以與環境無關的方式提供DOM操作。

注意:當應用程序上下文和渲染上下文不同時(例如將應用程序運行到Web Worker中時),Document可能在應用程序上下文中不可用。

假設我們在html中有一個元素:


我們可以注入DOCUMENT來獲取畫布HTMLElement:

@Component({
})
export class CanvasElement {
    constructor(@Inject(DOCUMENT) _doc: Document) {}
}

我們可以調用getElementById(),獲得畫布的HTMLElement。

@Component({
})
export class CanvasElement {
    constructor(@Inject(DOCUMENT) _doc: Document) {}
    renderCanvas() {
        this._doc.getElementById("canvas")
    }
}

我們還可以使用ElementRef和模板引用來安全地執行此操作,理解即可。

警告:要小心!直接與DOM交互是危險的,並且可能帶來XSS風險。

6. @Attribute裝飾器

我們在Angular應用中主要使用Component、Module和Directive裝飾器。

我們有一個Attribute裝飾器,它使我們能夠消除對靜態字符串的更改檢測,這樣在傳遞靜態字符串時就不會降低性能了。

Attribute裝飾器的值只檢查一次,之後就不再檢查了。它們的用法類似於@Input裝飾器:

@Component({
    ...
})
export class BlogComponent {
    constructor(@Attribute("type") private type: string ) {}
}

7. HttpInterceptor

就像美國的防空網一樣,這是Angular中非常強大的功能。它會攔截HttpRequest並處理它們。

大多數攔截器會在調用next.handle(transformedReq),以將傳出請求傳遞到鏈中的下一個攔截器之前對請求進行轉換。

在極少數情況下,攔截器可能希望自己完全處理請求,而不是委託給鏈的其餘部分。這種行為是允許的。

HttpInterceptor可用於:

  • 認證
  • 緩存
  • 偽後端
  • URL轉換
  • 修改標頭

它用起來很簡單,首先創建一個服務並實現HttpInterceptor接口。

@Injectable()
export class MockBackendInterceptor implements HttpInterceptor {
    constructor() {}
    intercept(req: HttpRequest, next: HttpHandler): Observable {
        ...
    }
}

然後將其它插入你的主模塊中:

@NgModule({
    ...
    providers: (
        {
            provide: HTTP_INTERCEPTORS,
            useClass: MockBackendInterceptor,
            multi: true
        }
    )
    ...
})
export class AppModule {

8. AppInitializer

有時我們確實希望在Angular應用啟動時運行一段代碼,這段代碼可能會加載一些設置,比如加載緩存,加載配置或進行某些簽入。AppInitialzer令牌可以幫助你解決這一問題。

APP_INITIALIZER:初始化應用時執行的函數。

它很容易使用。如果我們希望在Angular應用啟動時執行以下runSettings函數:

function runSettingsOnInit() {
    ...
}

只需轉到主要模塊AppModule,並將它添加到其NgModule裝飾器中的provider部分:

@NgModule({
    providers: (
        { provide: APP_INITIALIZER, useFactory: runSettingsOnInit }
    )
})

9. 引導監聽器

就像AppInitializer一樣,Angular還有一項功能,使我們能夠在引導組件時進行偵聽。它就是APP_BOOTSTRAP_LISTENER。

通過此令牌提供的所有回調將為每個引導的組件調用。

我們有很多理由來偵聽組件引導,例如,Router模塊使用它來破壞和創建基於路由導航的組件。

要使用APP_BOOTSTRAP_LISTENER,請使用回調函數將其添加到AppModule的provider部分中:

@NgModule({
    {
        provide: APP_BOOTSTRAP_LISTENER, multi: true, 
        useExisting: runOnBootstrap
    }
    ...
})
export class AppModule {}

10. NgPlural

複數表示是一個問題。我們需要一直根據單數/複數值來在我們的應用中正確定義語法。某些網站會使用(s)。比如:

1 component(s) removed
3 component(s) removed

讀者應在閱讀時自行刪除或添加(s)****。

Angular在其NgPlural指令中為我們解決了這個問題。

NgPlural基於數字值來添加/刪除DOM子樹,為複數量身定制。

顯示與切換錶達式值匹配的DOM子樹,否則顯示與切換錶達式的複數類別匹配的DOM子樹。

要使用此指令,你必須提供一個容器元素,該元素將(ngPlural)屬性設置為一個switch表達式。具有(ngPluralCase)的內部元素將根據其表達式顯示:

1 component removed 1">{{components}} components removed

看到了吧,當顯示“已刪除的組件”數量時,我們使用NgPlural指令刪除了(s)。它將顯示:

// if 1 component
1 component removed
// if 5 components
5 components removed

小結

全篇看下來,有沒有喪失信心、覺得自己老了?

不用擔心,我們所有人都有知識盲區。上面所列的內容只是其中一部分,Angular既龐大又復雜。可以試著查看其他Angular相關的內容,看看是否可以找出你以前從未聽說過的特性。期待你的發現。

原文鏈接
10 Useful Angular Features You’ve Probably Never Used