What is Standalone?
Angular 16 推出了 Standalone 的版本,
可以不用透過 NgModule 引用其他 standalone 的 Component,
在 Angular 16 之前,
要透過 module.ts 在其中定義方法來引用其他 Component:
// import 的程式碼都放在這個區塊
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
// Decorator 裝飾器
@NgModule({
declarations: [AppComponent], // 放入 Component, Directive, Pipe
imports: [BrowserModule, AppRoutingModule], // 放入此 NgModule 需要使用 & 依賴的其他 NgModule
providers: [], // 放入全域使用的 Service
bootstrap: [AppComponent], // 決定進入點要使用哪一個 Component, 預設使用 AppComponent
})
export class AppModule {}
而新的 Standalone 版本則是沒有了 module.ts 等檔案,
多了 app.config.ts 來定義 providers,
如果一個 Component 需要用到另一個 Component,
可以直接在其中引用,
若要在 AppComponent 中引用 HeaderComponent 可以這樣寫:
import { CommonModule } from "@angular/common";
import { Component } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { HeaderComponent } from "./header/header.component"; // 引用其他 Component
@Component({
selector: "app-root",
standalone: true, // 這裡定義了這個 Component 為 Standalone
imports: [CommonModule, HeaderComponent, RouterOutlet], // 這裡定義了這個 Component 需要使用 & 依賴的其他 Component
templateUrl: "./app.component.html",
styleUrl: "./app.component.css",
})
export class AppComponent {
title = "test-for-standalone-1";
}
What is Component?
Component 負責 定義 & 控制畫面,
讓 Angular 可以根據資料和程式邏輯呈現相對應的畫面,
通常由四個檔案組成一個 Component:
.component.css => 用於定義該元件的 CSS 樣式
.component.html => 作為該元件範本的 HTML 檔案
.component.ts => 存放該元件類別 Component 的 TypeScript 檔案
.component.spec.ts => 用於單元測試
解析 app.component.ts:
// import 的程式碼都放在這個區塊
import { CommonModule } from "@angular/common";
import { Component } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { HeaderComponent } from "./header/header.component"; // 引用其他 Component
// Decorator 裝飾器
@Component({
selector: "app-root",
standalone: true, // 這裡定義了這個 Component 為 Standalone
imports: [CommonModule, HeaderComponent, RouterOutlet], // 這裡定義了這個 Component 需要使用 & 依賴的其他 Component
templateUrl: "./app.component.html",
styleUrl: "./app.component.css",
})
export class AppComponent {
title = "test-for-standalone-1";
}
@Component:
selector
=> CSS 選擇器它告訴 Angular 在 Template 中找到相應的位置之後, 創建並插入該 Component 實體
以上述為例, 在 HTML 中我們可以使用
<app-root></app-root>
來顯示該 Component 的內容
standalone
=> 定義此 Component 為 StandalonetemplateUrl
=> 此 Component 的 Template 檔案位置(相對位置)template
=> 與 templateUrl 的用途類似, 但這裡是直接放 HTML 的語法(不建議使用)styleUrls
=> 樣式檔檔案位置(相對位置)styles
=> 與 styleUrls 類似, 但這裡可以直接放 CSS 的語法(不建議使用)providers
=> 與 NgModule 的 providers 類似, 但作用區域不同
What is Template?
Template 是由 HTML + CSS 再加上一些 Angular 提供的 符號 & 屬性 所組成
Template 上的 元素 & 資料 都是靜態的,
搭配 Component 裡的 TypeScript 即可控制 Template 中要顯示的內容.
Single Page Application
Angular 的架構是一個 SPA 單頁應用, 起始頁為 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TestForStandalone1</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<!-- 插入 Component 在這裡 -->
<app-root></app-root>
</body>
</html>
在 index.html 中, 可以看到這裡定義了一些常見的 html 標籤,
可以注意到在 <body></body>
裡面, 放著 AppComponent 的選擇器標籤,
因此當進入 index.html 時, <body></body>
中的 <app-root></app-root>
會被替換成 AppComponent 內容,
AppComponent 的內容便是 templateUrl + styleUrls + ts 所組成的畫面
接著看到 angular.json:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"Test": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test",
// 這裡定義了起始頁面
"index": "src/index.html",
// 這裡定義了起始的ts執行檔
"main": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.css"],
"scripts": []
},
.
.
.
在 angular.json 中:
Index: src/index.html
=> 決定 index.html 為起始頁面也是唯一頁面main: src/main.ts
=> 決定 main.ts 為起始的 ts 執行檔
再來看到 main.ts:
// Angular 16
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { AppComponent } from "./app/app.component";
bootstrapApplication(AppComponent, appConfig).catch((err) =>
console.error(err)
);
main.ts 透過 bootstrapApplication
啟動 AppComponent
並傳入 appConfig
.
而在 angular 16 之前的版本則是會透過 透過 bootstrapModule
啟動 AppModule
:
// Angular 16 之前
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
運作流程差異:
Berfore Angular 16:
- index.html => main.ts => app.module.ts => app.component.ts
After Angular 16:
- index.html => main.ts => app.config.ts => app.component.ts
參考
文章閱讀