iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 16
2
Modern Web

Angular 2 之 30 天邁向神乎其技之路系列 第 16

[Day 16] Angular 2 Module ( 2 )

  • 分享至 

  • xImage
  •  

接續 Angular 2 Module ( 1 )

Feature Module

Angular 一定會有一個 root module,但你也可以有 feature module,接著就來看看怎麼建立吧!
接續上一篇,假設我們依舊有CreditCardMaskPipeCreditCardServiceCreditCardComponent,但我們不想要直接放進 root module,我們想要再建立一個 module 來包裝這些東西,這時候新的 module 就是 feature module 了。

首先我們先創一個新的資料夾給新的 module

├── app
│   ├── app.component.ts
│   └── app.module.ts
├── credit-card
│   ├── credit-card-mask.pipe.ts
│   ├── credit-card.component.ts
│   ├── credit-card.module.ts
│   └── credit-card.service.ts
├── index.html
└── main.ts

現在有兩個資料夾裝有 module 了:app.module.tscredit-card.module.ts

先看看後者

//credit-card/credit-card.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CreditCardMaskPipe } from './credit-card-mask.pipe';
import { CreditCardService } from './credit-card.service';
import { CreditCardComponent } from './credit-card.component';

@NgModule({
  imports: [CommonModule],
  declarations: [
    CreditCardMaskPipe,
    CreditCardComponent
  ],
  providers: [CreditCardService],
  exports: [CreditCardComponent]
})
export class CreditCardModule {}

我們已經知道這個是一個 feature module,但看一下內容其實跟 root module 長得很像,但仍然有幾點不同:

  • 引入 CommonModule 而非 BrowserModule
  • @NgModule 裡面多了 exportdeclarations 宣告用到的物件是 private,為了讓我們的 module 在被其他 module 使用的時候也可以動用自己模組裡的物件,export 可以讓 CeditCardComponent 變成 public, up 因為 AppComponent 之後會用到。但是 CreditCardMaskPipe 則繼續保持 private,因為這只有在自己模組中的溝通才會用到。

接著來看看 AppModule 如何使用 CreditCardModule

app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { CreditCardModule } from '../credit-card/credit-card.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    BrowserModule,
    CreditCardModule
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

imports 中引入要使用的其他模組

剛剛已經說 CeditCardComponent 被模組公開了,所以 AppComponent 這邊就可以拿來使用囉

//app/app.component.ts

...
@Component({
  ...
  template: `
    ...
    <app-credit-card></app-credit-card>
  `
})
export class AppComponent {}

指令衝突

因為我們不再直接定義每個 component 他們所需要的 component 和 directive。所以我們需要知道 Angular Module 如何處理指令和組件同時作用在同一個元件上時候的衝突。也就是都針對同一個 selector 時候會怎麼做。

現在假設有兩個指令,針對同一個元件作用。

使背景變藍,字變灰

//blue-highlight.directive.ts
import { Directive, ElementRef, Renderer } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class BlueHighlightDirective {
  constructor(renderer: Renderer, el: ElementRef) {
    renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'blue');
    renderer.setElementStyle(el.nativeElement, 'color', 'gray');
  }
}

背景變黃

//yellow-highlight.directive.ts
import { Directive, ElementRef, Renderer } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class YellowHighlightDirective {
  constructor(renderer: Renderer, el: ElementRef) {
    renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'yellow');
  }
}

一個要讓背景變黃,一個要讓背景變藍,這時候會怎樣?

AppModule 這樣定義

//app.module.ts

// Imports

@NgModule({
  imports: [BrowserModule],
  declarations: [
    AppComponent,
    BlueHighlightDirective,
    YellowHighlightDirective
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

我們的組件長這樣,其中的 appHighlight 就是被兩個指令同時作用的東西。

//app.component.ts

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

@Component({
  selector: 'app-root',
  template: '<h1 appHighlight>My Angular 2 App</h1>'
})
export class AppComponent {}

所以最後結論是如何?

答案是字是灰色,背景是黃色 (Plurk)

還記得剛剛的 module 嗎?

declarations: [
  ...,
  BlueHighlightDirective,
  YellowHighlightDirective
]

BlueHighlightDirective 先被執行, YellowHighlightDirective 再被執行,所以背景先變藍色後來又變成黃色。

結論就是當衝突發生時,當許多指令作用在同一個元件時,會依照順序執行。


上一篇
[Day 15] Angular 2 Module ( 1 )
下一篇
[Day 17] Angular 2 替 Component 加上 CSS 的所有招數
系列文
Angular 2 之 30 天邁向神乎其技之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言