深入瞭解angular中的@Component裝飾器

2022-05-27 22:01:09
Component是Directive的子類,它是一個裝飾器,用於把某個類標記為Angular元件。下面本篇文章就來帶大家深入瞭解angular中的@Component裝飾器,希望對大家有所幫助。

一、 @Component 裝飾器

1.1 @Component 裝飾器的用途

宣告一個元件時,在元件類的之上要用@Component裝飾器來告知Angular這是一個元件。【相關教學推薦:《》】

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-product-alerts',
  templateUrl: './product-alerts.component.html',
  styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

1.2 @Component 裝飾器的常用選項

@Component 裝飾器繼承於 Directive ,這個css選擇器用於在模板中標記出該指令,並觸發該指令的範例化。

1.2.1 繼承自@Directive裝飾器的選項

選項型別說明
selectorstringcss選擇器名,用於在模板中標記出該指令(元件),並觸發其範例化
inputsstring[]Angular 會在變更檢測期間自動更新輸入屬性。inputs 屬性定義了一組從 directiveProperty 指向 bindingProperty 的設定項:
· directiveProperty 用於指定要寫入值的指令內屬性。
· bindingProperty 用於指定要從中讀取值的 DOM 屬性。當沒有提供 bindingProperty 時,就假設它和 directiveProperty 一樣。
outputsstring[]一組可供事件繫結的輸出屬性。當輸出屬性發出事件時,就會呼叫模板中一個附加到該事件的處理器。每個輸出屬性都會把 directiveProperty 對映到 bindingProperty:
· directiveProperty 指定要發出事件的元件屬性。
· bindingProperty 指定要附加事件處理器的 HTML 屬性。
providesProvider[]服務提供商的集合
exportAsstring一個或多個名字,可以用來在模板中把該指令賦值給一個變數。當有多個名字時,請使用逗號分隔它們。
queries{[key:string]:any}設定將要注入到該指令中的一些查詢。內容查詢會在呼叫 ngAfterContentInit 回撥之前設定好。 試圖查詢會在呼叫 ngAfterViewInit 回撥之前設定好。
jittrue如果為 true,則該指令/元件將會被 AOT 編譯器忽略,因此永遠只會被 JIT 編譯。這個選項是為了支援未來的 Ivy 編譯器,目前還沒有效果。
host{[key:string]:string}使用一組鍵-值對,把類的屬性對映到宿主元素的繫結(Property、Attribute 和事件)。Angular 在變更檢測期間會自動檢查宿主 Property 繫結。 如果繫結的值發生了變化,Angular 就會更新該指令的宿主元素。當 key 是宿主元素的 Property 時,這個 Property 值就會傳播到指定的 DOM 屬性。當 key 是 DOM 中的靜態 Attribute 時,這個 Attribute 值就會傳播到宿主元素上指定的 Property 去。對於事件處理:
· 它的 key 就是該指令想要監聽的 DOM 事件。 要想監聽全域性事件,請把要監聽的目標新增到事件名的前面。 這個目標可以是 window、document 或 body。
· 它的 value 就是當該事件發生時要執行的語句。如果該語句返回 false,那麼就會呼叫這個 DOM 事件的 preventDefault 函數。 這個語句中可以參照區域性變數 $event 來獲取事件資料。

1.2.2 @Component自己特有的選項

選項型別說明
changeDetectionChangeDetectionStrategy當元件範例化之後,Angular 就會建立一個變更檢測器,它負責傳播元件各個繫結值的變化。 該策略是下列值之一:
· ChangeDetectionStrategy#OnPush(0) 把策略設定為 CheckOnce(按需)。
· ChangeDetectionStrategy#Default(1) 把策略設定為 CheckAlways。
viewProvidersProvider[]定義一組可注入物件,它們在檢視的各個子節點中可用
moduleIdstring包含該元件的那個模組的 ID。該元件必須能解析模板和樣式表中使用的相對 URL。 SystemJS 在每個模組中都匯出了 __moduleName 變數。在 CommonJS 中,它可以設定為module.id。
templateUrlstring元件模板檔案的 URL。如果提供了它,就不要再用 template 來提供內聯模板了。
templatestring元件的內聯模板。如果提供了它,就不要再用 templateUrl 提供模板了。
styleUrlsstring[]一個或多個 URL,指向包含本元件 CSS 樣式表的檔案。
stylesstring[]本元件用到的一個或多個內聯 CSS 樣式。
animationsany[]一個或多個動畫 trigger() 呼叫,包含一些 state() 和 transition() 定義。
encapsulationViewEncapsulation供模板和 CSS 樣式使用的樣式封裝策略。取值為:
· ViewEncapsulation.ShadowDom:使用 Shadow DOM。它只在原生支援 Shadow DOM 的平臺上才能工作。
· ViewEncapsulation.Emulated:使用墊片(shimmed) CSS 來模擬原生行為。
· ViewEncapsulation.None:使用全域性 CSS,不做任何封裝。
如果沒有提供,該值就會從 CompilerOptions 中獲取它。預設的編譯器選項是 ViewEncapsulation.Emulated。如果該策略設定為 ViewEncapsulation.Emulated,並且該元件沒有指定 styles 或 styleUrls,就會自動切換到 ViewEncapsulation.None。
interpolation[string, string]改寫預設的插值表示式起止分界符({{ 和 }})
entryComponentsArray<Typeany[]>
preserveWhitespacesboolean為 true 則保留,為 false 則從編譯後的模板中移除可能多餘的空白字元。 空白字元就是指那些能在 JavaScript 正規表示式中匹配 \s 的字元。預設為 false,除非通過編譯器選項改寫了它。

二、 selector 選擇器

可使用下列形式之一:

  • element-name: 根據元素名選取
  • [attribute]: 根據屬性名選取
  • .class: 根據類名選取
  • [attribute=value]: 根據屬性名和屬性值選取
  • not(sub_selector): 只有當元素不匹配子選擇器 sub_selector 的時候才選取
  • selector1, selector2: 無論 selector1 還是 selector2 匹配時都選取

2.1 element-name: 根據元素名選取

@Component({
    selector: 'app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
<app-element></app-element>

2.2 [attribute]: 根據屬性名選取

@Component({
    selector: '[app-element]',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
<div app-element></div>

2.3 .class: 根據類名選取

@Component({
    selector: '.app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css']
})
<div class="app-element"></div>

三、 host: {[key:string]:string}

使用一組鍵-值對,把類的屬性對映到宿主元素的繫結(Property、Attribute 和事件)。
Angular 在變更檢測期間會自動檢查宿主 Property 繫結。 如果繫結的值發生了變化,Angular 就會更新該指令的宿主元素。

  • 當 key 是宿主元素的 Property 時,這個 Property 值就會傳播到指定的 DOM 屬性。
  • 當 key 是 DOM 中的靜態 Attribute 時,這個 Attribute 值就會傳播到宿主元素上指定的 Property 去。
  • 注意屬性的值預設為變數,如果直接使用屬性值,需要加字串單引號或者雙引號,變數直接在元件裡定義即可

對於事件處理:

  • 它的 key 就是該指令想要監聽的 DOM 事件。 要想監聽全域性事件,請把要監聽的目標新增到事件名的前面。 這個目標可以是 window、document 或 body。
  • 它的 value 就是當該事件發生時要執行的語句。如果該語句返回 false,那麼就會呼叫這個 DOM 事件的 preventDefault 函數。 這個語句中可以參照區域性變數 $event 來獲取事件資料。

3.1 attributeproperty

  • property:dom元素作為物件附加的內容,例如childNodes、firstChild等
  • attribute:HTML標籤特性是dom節點自帶的屬性

異同:

  • 部分屬性既屬於 property ,又屬於 attribute ,比如 id
  • attribute 初始化後不會再改變; property 預設值為初始值,會隨著 dom 更新

所以在 angular2 中雙向繫結實現是由 dom 的 property 實現的,所以指令繫結的是 property ,但是在某些情況下 dom 不存在某個 property 比如 colspan,rowspan 等,這時想要繫結 html 標籤特性需要用到 attr:

<table width="100%" border="10px solid">
  <tr>
    <th>Month</th>
    <th>Savings</th>
  </tr>
  <tr>
    <td [attr.colspan]=colnum>January</td>
  </tr>
  <tr>
    <td [attr.colspan]=colnum>February</td>
  </tr>
</table>

let colnum:number = 2;

3.2 使用 host 繫結 class

@Component({
    selector: '.app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css'],
    host: {
        '[class.default-class]': 'useDefault'
    },
    encapsulation: ViewEncapsulation.None // 讓宿主元素也用上 element.component.css 樣式。否則,預設膠囊封裝避免CSS汙染。
})
export class AppElementComponent {
  @Input() useDefault = true;
}
<div class="app-element"></div>

3.3 使用 host 繫結 style

@Component({
    selector: '.app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css'],
    host: {
        '[style.background]': 'inputBackground'
    }
})
export class AppElementComponent {
  @Input() inputBackground = 'red';
}
<div class="app-element"></div>

3.4 使用 host 繫結事件

@Component({
    selector: '.app-element',
    template:  './element.component.html',
    styleUrls: ['./element.component.css'],
    host: {
        '(click)': 'onClick($event)'
    }
})
export class AppElementComponent {
  public onClick($event) {
    console.log($event);
  }
}
<div class="app-element"></div>

四、 encapsulation(封裝)

供模板和 CSS 樣式使用的樣式封裝策略。

4.1 Web Components

通過一種標準化的非侵入的方式封裝一個元件,每個元件能組織好它自身的 HTML 結構、CSS 樣式、JavaScript 程式碼,並且不會干擾頁面上的其他元素。

Web Components 由以下四種技術組成:

  • Custom Elements: 自定義元素HTML
  • Templates: HTML模板
  • Shadow DOM: 影子DOMHTML
  • Imports: HTML匯入

4.2 Shadow DOM

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Shadow DOM</title>
    <style type="text/css">
        .shadowroot_son {
            color: #f00;
        }
    </style>
</head>
<body>
<p>我不在 Shadow Host內</p>
<div>Hello, world!</div>
<script>
 // 影子宿主(shadow host)
 var shadowHost = document.querySelector('.shadowhost');
 // 建立影子根(shadow root)
 var shadowRoot = shadowHost.createShadowRoot();
 // 影子根作為影子樹的第一個節點,其他的節點比如p節點都是它的子節點。
 shadowRoot.innerHTML = '<p>我在 Shadow Host內</p>';
</script>
</body>
<html>

4.3 ViewEncapsulation

ViewEncapsulation 允許設定三個可選的值:

  • ViewEncapsulation.Emulated: 無 Shadow DOM,但是通過 Angular 提供的樣式包裝機制來封裝元件,使得元件的樣式不受外部影響。這是 Angular 的預設設定。
  • ViewEncapsulation.ShadowDom: 使用原生的 Shadow DOM 特性
  • ViewEncapsulation.None: 無 Shadow DOM,並且也無樣式包裝

4.3.1 ViewEncapsulation.None

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <h4>Welcome to Angular World</h4>
    <p class="greet">Hello {{name}}</p>
  `,
  styles: [`
    .greet {
      background: #369;
      color: white;
    }
  `],
  encapsulation: ViewEncapsulation.None // None | Emulated | ShadowDom
})
export class AppComponent {
  name: string = 'Semlinker';
}

ViewEncapsulation.None 設定的結果是沒有 Shadow DOM,並且所有的樣式都應用到整個 document,換句話說,元件的樣式會受外界影響,可能被覆蓋掉。

4.3.2 ViewEncapsulation.Emulated

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  ...,
  encapsulation: ViewEncapsulation.Emulated // None | Emulated | ShadowDom
})
export class AppComponent {
  name: string = 'Semlinker';
}

ViewEncapsulation.Emulated 設定的結果是沒有 Shadow DOM,但是通過 Angular 提供的樣式包裝機制來封裝元件,使得元件的樣式不受外部影響。雖然樣式仍然是應用到整個 document,但 Angular 為 .greet 類建立了一個 [_ngcontent-cmy-0] 選擇器。可以看出,我們為元件定義的樣式,被 Angular 修改了。其中的 _nghost-cmy- 和 _ngcontent-cmy- 用來實現區域性的樣式

4.3.3 ViewEncapsulation.ShadowDom

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  ...,
  encapsulation: ViewEncapsulation.ShadowDom // None | Emulated | ShadowDom
})
export class AppComponent {
  name: string = 'Semlinker';
}

ViewEncapsulation.ShadowDom 設定的結果是使用原生的 Shadow DOM 特性。Angular 會把元件按照瀏覽器支援的 Shadow DOM 形式渲染

更多程式設計相關知識,請存取:!!

以上就是深入瞭解angular中的@Component裝飾器的詳細內容,更多請關注TW511.COM其它相關文章!