iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 6
1
Modern Web

Angular 8 從推坑到放棄系列 第 6

[Day 05] Angular 是如何運作的

撰寫第一個專案後,會不會對 Angular 的運作有所好奇呢?

好我知道很多人不會XD,但是 如果要加深使用該技術的能力

就要完整的了解他整個運作方式.

一切都起於 index.html

從 angular.json 檔內可以看到 architect 中的 index 屬性設定為 index.html,此為起始頁面,同時也是

Angular 專案中的唯一頁面,因為 Angular 就是一個 SPA(Single Page Application)網站,所有頁面的切換

與介面內容的改變都是透過 JavaScript 做即時的動態切換.

在正常運作下,使用者對網站發出請求後網站會回傳 index.html,而在 index.html 內會包含 main.ts 的

JavaScript(當然還有很多東西)。

流程:index.html > main.ts

當使用 ng serve 或是 ng build 時,可以看到編譯所產生 index.html 載入了 main.js 。

Angular 專案的進入點 main.ts

Angular 是怎麼知道AppModule是我們應用程式的入口呢?我們可以打開angular.json

看到 architect 中的 main 設定,裡面設定了main.ts,這隻程式在Angular CLI編譯打包程式時,會作為主要

的程式進入點,開啟專案目錄下

src\main.ts 檔可以發現 Angular 將 AppModule 當作起始模組載入:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

什麼是 Components

Angular 引入了 W3C Web Component的概念,也就是一個Angular 基本上是由數個元件 (component) 組成

的,所以在設計時我們可以適當的將預期的畫面拆解成數個 (component),然後各司其職,並且適當的彼此溝通,來

完成我們預期的程式。

而componet又是由什麼組成的呢?

看上面官方的架構圖中,是由template、metadata、component所構成的,這三個是一個component必備的元素。

那麼要如何建立一個component呢?其實上一篇文章中,我們使用Angular CLI建立一個專案時,就已經有一個最基

本app-root的component

我們可以打開src/app/app.component.ts,看到以下程式

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
}

在這裡我們可以看到@Component就是用來將AppComponent這個class"裝飾"成一個component

這是在 Javascript es6 提出來的一種decorator(裝飾器)語法,使用@#XXXX 來從不同的切面對程式進行不同角色的描述.

雖然大部分的瀏覽器都還不支援,但我們使用TypeScript撰寫時,Typescript 編譯器(簡稱 tsc) 就能將程式轉換

成大部分瀏覽器都看得懂得程式碼了!

Angular 製作了許多的decorator,而@component就是其中一個,因此只要在class上面使用@component宣告,

Angular 核心就能夠知道這是一個component囉!

而裡面目前看到的三個屬性:

  • selector: 用來表示在HTML上的哪個element要套用這個component

  • templateUrl: 用來表示這個component的view存放位置

  • styleUrls: 用來加入專屬於這個component的css檔案位置

新增一個 Components

我們可以透過 Angular CLI 去新增一個 Components

ng generate component test-component
OR
ng g c test-component

之後就會新增一個 test-components資料夾,並且新增以下檔案

Template

其中裡面的test-component.component.html檔就是template,它看起來像是一個html的檔案,可以在裡面用資

料綁定與事件綁定與controller裡的物件做繫結。
下面是一個 test-component.component.html 的範例:

<p>test-component works!</p>

而test-componentcomponent.ts 則是透過上述的 templateUrl,去選取指定的 template

而假如 component 中的 template 不大的話,其實可以寫在 component 裡面

我們可以打開 test-component.component.ts 並且修改它成為

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

@Component({
  selector: 'app-test-component',
  // 修改為 template
  template: '<p>Use Template by Component Decorator</p>',
  styleUrls: ['./test-component.component.css']
})
export class TestComponentComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

顯示結果如下:

什麼是 Module

新增完一個 component 後,這個 component 還不能使用 ,因為還沒有被 引用,引用到 Angular 專案中,而要引用

就必須要加入 module之中,一個專案裡面可以有好幾個 angular module,,而angular專案初始化的時候已經有

一個 AppModule 了 ,我們可以先把他引用到該 module中

在使用新增的component 之前,先來介紹 Angular 的 Module,在Angular 裡面的Module,是透過 裝飾器

@NgModule 宣告的,Module 其實就是 Component 的集合,可以想像是一個群組,Module 最主要的用途就是封

裝,把這個Module會用到的元件都封裝在一起,可以將 不相關的 Components 加以隔離。

我們可以打開src/app/app.module.ts,看到以下程式

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { TestComponentComponent } from './components/test-component/test-component.component';

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

看起來很複雜,但是只要裝飾器中的 4個參數代表的功能,就可以知道 Module如何使用
@ NgModule的參數內容如下:

  1. declarations: []:宣告跟View有關的原件,這個 module 擁有那些相關的 components、directives、pipes,這個是我們等一下要將 componets 引用的地方

  2. exports:[]:module下哪些類別是可以公開給外部使用的

  3. imports:[]:在這個module下,我們需要匯入哪些其他的module給components、directives、pipes使用

  4. providers:[]:宣告在這裏面的Service,可以讓Modules內所有的組件使用。

  5. bootstrap:[] : 唯一在 app.module.ts 有這個屬性,啟動 專案的根元件

使用 第一個 建立的 components

透過上面的參數,我們可以知道 要將components 顯示在畫面上的需要在 declarations部分加入 剛剛新增的 component,並且透過 selector 在指定的地方顯示畫面

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { TestComponentComponent } from './components/test-component/test-component.component';

@NgModule({
  declarations: [
    AppComponent,
    // 加入的部分
    TestComponentComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

之後我們可以在 AppModule 中的各個地方使用 TestComponent,可以透過
TestCompoent 中指定的 selector 在指定的地方顯示 component,例如我要在 AppComponent 中顯示 TestComponent,只要在 AppComponent 中
加入 app-test-component 就可以在畫面上顯示出來.

修改 src/app/app.components.html為:

<h3>Hi, This is Second sample</h3>
<app-test-component></app-test-component>

之後在 畫面上就會顯示

當然你也可以加入多個 components
例如像這樣修改 src/app/app.components.html

修改 src/app/app.components.html為:

<h3>Hi, This is Second sample</h3>
<app-test-component></app-test-component>
<app-test-component></app-test-component>
<app-test-component></app-test-component>

之後在 畫面上就會顯示為:

參考

  1. [Angular2速成班]來寫個TodoApp(1)-基本原理與架構

  2. [功能介紹-1] Angular架構

  3. 2017,讓我們再來看看 Web Components 吧!

  4. Angular - Module簡介

  5. 裝飾器


上一篇
[Day 04 ]為中大型的Angular專案設計專案結構
下一篇
[Day 06 ]Angular 資料繫結
系列文
Angular 8 從推坑到放棄30

尚未有邦友留言

立即登入留言