撰寫第一個專案後,會不會對 Angular 的運作有所好奇呢?
好我知道很多人不會XD,但是 如果要加深使用該技術的能力
就要完整的了解他整個運作方式.
從 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 是怎麼知道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));
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檔案位置
我們可以透過 Angular CLI 去新增一個 Components
ng generate component test-component
OR
ng g c test-component
之後就會新增一個 test-components資料夾,並且新增以下檔案
其中裡面的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() {
}
}
顯示結果如下:
新增完一個 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的參數內容如下:
declarations: []:宣告跟View有關的原件,這個 module 擁有那些相關的 components、directives、pipes,這個是我們等一下要將 componets 引用的地方
exports:[]:module下哪些類別是可以公開給外部使用的
imports:[]:在這個module下,我們需要匯入哪些其他的module給components、directives、pipes使用
providers:[]:宣告在這裏面的Service,可以讓Modules內所有的組件使用。
bootstrap:[] : 唯一在 app.module.ts 有這個屬性,啟動 專案的根元件
透過上面的參數,我們可以知道 要將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>
之後在 畫面上就會顯示為: