開始使用獨立元件

1. 簡介

建構目標

在本程式碼研究室中,您將使用 Angular v14 建構野生動物相片庫應用程式。完成的應用程式會顯示一組相片,並提供傳送訊息表單,讓使用者與攝影師聯絡,以及聊天視窗,讓使用者瞭解相片中動物的相關資訊。

您可以使用 Angular 14 和新的獨立元件功能,建構應用程式中的所有內容。

所有 Angular 架構和 Angular CLI 參照資料均反映 Angular 14 版。獨立元件是 Angular 14 的預先發布版功能,因此您必須使用 Angular 14 建立全新應用程式。獨立元件可讓您以簡單的方式建構 Angular 應用程式。獨立元件、獨立指示詞和獨立管道旨在減少 NgModules 的需求,以便簡化撰寫體驗。獨立元件可充分利用現有的 Angular 程式庫生態系統。

這是您今天要建構的應用程式。

已完成的申請表

學習目標

  • 如何使用 Angular CLI 建立新專案的結構
  • 如何使用 Angular 獨立元件,簡化 Angular 應用程式的開發作業
  • 如何建立獨立元件,也就是如何建構 UI 並新增一些商業邏輯
  • 如何使用獨立元件啟動應用程式
  • 如何延遲載入獨立元件
  • 如何使用 Dialogflow Messenger 在獨立元件中嵌入聊天對話
  • 如何使用 Google Cloud CLI (gcloud) 將 Angular 應用程式部署至 Google Cloud App Engine

軟硬體需求

  • Gmail 或 Google Workspace 帳戶
  • 具備下列主題的基本知識
    • HTML。如何建立元素。
    • CSS 和 less。如何使用 CSS 選取器,以及建立樣式定義檔案。
    • TypeScript 或 JavaScript。如何與 DOM 結構互動。
    • 以及 GitHub。如何建立存放區分支並加以複製。
    • 指令列介面,例如 bashzsh。如何瀏覽目錄和執行指令。

2. 環境設定

設定本機環境

如要完成本程式碼研究室,您必須在本機電腦上安裝下列軟體。

  • Node.js 的 LTS 或維護 LTS 版本。用於安裝 Angular 架構和 Angular CLI。

    Node 版本

    由 Angular 支援

    14.15 以上版本

    有權限

    16.10 以上版本

    有權限

    18.1.0

    不支援

    如要確認本機電腦上的 Node.js 版本,請在指令列視窗中執行下列 node 指令。
    node -v
    
  • 程式碼編輯器或 IDE。用於開啟及編輯檔案。Visual Studio Code 或您選擇的其他程式碼編輯器。

安裝 Angular CLI

設定所有依附元件後,請執行下列 npm 指令,透過指令列視窗安裝 Angular CLI。

npm install --global @angular/cli

如要確認設定是否正確,請透過指令列執行下列 Angular 指令。

ng version

如果 Angular 指令成功完成,您應該會收到類似下方螢幕截圖的訊息。

終端機輸出的 Angular 版本

原始碼和圖片

您將從頭開始建立整個應用程式,而這個逐步程式碼研究室將提供協助。請注意,GitHub 存放區包含最終程式碼。如果遇到問題,請查看最終程式碼和圖片庫頁面上顯示的圖片。

下載原始碼。

  1. 在瀏覽器中前往以下頁面。
    https://github.com/angular/codelabs/tree/standalone-components
    
  2. 在指令列視窗中,分支並複製存放區。

在下一個步驟中,建構相片庫應用程式。

3. 建立新的應用程式

如要建立初始範例應用程式,請完成下列動作。

使用 Angular CLI 建立新工作區。如要進一步瞭解 Angular CLI 和 Angular 架構,請前往 angular.io

建立新專案

在指令列視窗中完成下列步驟。

  1. 輸入下列 Angular 指令,建立名為 photo-gallery-app 的新 Angular 專案。
    ng new photo-gallery-app
    
  2. 在每次提示時,接受預設選項。Angular 架構會安裝必要的套件和依附元件。這項程序可能需要幾分鐘的時間。

Angular CLI 完成後,您會擁有一個新的 Angular 工作區,以及一個立即可用的簡單應用程式。

新應用程式的結構與標準的 Angular 應用程式類似。新應用程式中的 NgModule 不適用於本程式碼研究室。

移除應用程式模組

如要移除應用程式模組,請完成下列步驟。

  1. 前往新 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 刪除 app.module.ts 檔案。

刪除應用程式模組後,應用程式就不會有模組。您的應用程式只有一個元件,即應用程式元件。您必須將該元件宣告為獨立元件。

宣告獨立元件

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 開啟 app.component.ts 檔案。
  3. 將以下參數和值加入修飾符清單。
    standalone: true
    
    app.component.ts 檔案應與下列程式碼範例高度相符。
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  4. 儲存 app.component.ts 檔案。

編譯新的獨立應用程式

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄
  2. 輸入下列 Angular 指令,編譯新應用程式。
    ng serve
    

您的應用程式應無法編譯。別擔心,你只需要修正幾個問題。

使用 BootstrapApplication API

如要讓應用程式在沒有 NgModule 的情況下執行,您必須使用 bootstrapApplication API 將獨立元件做為根元件。

移除應用程式模組的參照

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src 目錄
  2. 開啟 main.ts 檔案。
  3. 由於您不再有應用程式模組,請移除下列匯入程式碼。
    import { AppModule } from './app/app.module';
    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    
  4. 由於您不再有應用程式模組,因此請移除下列 Bootstrap 程式碼。
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
    
    main.ts 檔案應與下列程式碼範例相符。
    import { enableProdMode } from '@angular/core';
    import { environment } from './environments/environment';
    
    if (environment.production) {
      enableProdMode();
    }
    

新增 bootstrapApplication 元件

在程式碼編輯器中完成以下動作。

  1. 前往新 photo-gallery-app 專案目錄中的 src 目錄。
  2. 開啟 main.ts 檔案。
  3. @angular/platform-browser 服務匯入 bootstrapApplication 元件。
    import { bootstrapApplication } from '@angular/platform-browser';
    
  4. 加入以下程式碼來啟動應用程式。
    bootstrapApplication(AppComponent).catch(err => console.error(err));
    
  5. 匯入元件和必要的程式庫。
    import { AppComponent } from './app/app.component';
    
    main.ts 檔案應符合下列程式碼範例。
    import { enableProdMode } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { AppComponent } from './app/app.component';
    import { environment } from './environments/environment';
    
    if (environment.production) {
      enableProdMode();
    }
    
    bootstrapApplication(AppComponent).catch(err => console.error(err));
    

新增路由器和通用模組

如要使用路由器和其他常見模組功能,你必須直接將每個模組匯入元件中。

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 開啟 app.component.ts 檔案。
  3. 將必要模組匯入元件。
    import { CommonModule } from '@angular/common';
    import { RouterModule } from '@angular/router';
    
  4. 在元件中新增匯入項目。
    imports: [CommonModule, RouterModule],
    
    app.component.ts 檔案應與下列程式碼範例相符。
    import { Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { RouterModule } from '@angular/router';
    
    @Component({
      selector: 'app-root',
      imports: [CommonModule, RouterModule],
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  5. 儲存 app.component.ts 檔案。

編譯並執行新的獨立應用程式

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,編譯及執行應用程式並開啟網路伺服器。您可能需要在執行應用程式前關閉 IDE,以便移除任何編譯錯誤。
    ng serve
    

開發伺服器應在 4200 通訊埠上執行。先前的所有錯誤都應該消失,編譯也應該會成功。非常好,您已成功建立 Angular 應用程式,該應用程式不需模組即可執行,且含有獨立元件。

  1. 接下來,您將美化應用程式可顯示一些相片。

4. 顯示相片

您的新應用程式是相片庫,因此應會顯示一些相片。

元件是 Angular 應用程式的核心構成元素。元件有 3 個主要層面。

  • 範本的 HTML 檔案
  • 樣式的 CSS 檔案
  • 應用程式行為的 TypeScript 檔案

將相片移至應用程式

這些相片會顯示在您先前從 GitHub 下載的應用程式中。

  1. 前往 GitHub 專案的 src/assets 目錄。
  2. 複製檔案並貼到 photo-gallery-app 專案目錄中的 analogue 目錄。

建立 HTML 範本

app.component.html 檔案是與 AppComponent 元件相關聯的 HTML 範本檔案。

在程式碼編輯器中完成以下動作。

  1. 前往新 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 開啟 app.component.html 檔案。
  3. 刪除所有現有的 HTML。
  4. 複製下列程式碼範例中的 HTML。
    <article>
        <h1>Above and below the Ocean</h1>
            <h2>A taste of the Australia and Galapagos Wildlife, meet my friends!</h2>
            <section>
                <section class="row">
                    <div class="column">
                      <img src="/assets/49412593648_8cc3277a9c_c.jpg">
                      <img src="/assets/49413271167_22a504c3fa_w.jpg">
                      <img src="/assets/47099018614_5a68c0195a_w.jpg">
                    </div>
                    <div class="column">
                      <img src="/assets/41617221114_4d5473251c_w.jpg">
                      <img src="/assets/47734160411_f2b6ff8139_w.jpg"> 
                      <img src="/assets/46972303215_793d32957f_c.jpg">
                    </div>
                    <div class="column">
                      <img src="/assets/45811905264_be30a7ded6_w.jpg">
                      <img src="/assets/44718289960_e83c98af2b_w.jpg">
                      <img src="/assets/46025678804_fb8c47a786_w.jpg">
                    </div>
                  </section>
            </section>
    </article
    
  5. 儲存 app.component.html 檔案。

建立樣式定義檔

在程式碼編輯器中完成以下動作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src 目錄。
  2. 開啟 styles.css 檔案。
  3. 複製下列程式碼範例中的 CSS。
    article {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      font-family: 'Raleway';
    }
    
    h1 {
      color: #4479BA;
      text-align: center;
      font-size: xx-large;
    }
    
    h2 {
      color: rgb(121, 111, 110);
      text-align: center;
    }
    
    .row {
      display: flex;
      flex-wrap: wrap;
      padding: 0 4px;
    }
    
    /*   Create four equal columns that sits next to each other */
    .column {
      flex: 25%;
      padding: 0 4px;
    }
    
    .column img {
      margin-top: 8px;
      vertical-align: middle;
      width: 100%;
    }
    
    .link_button {
      -webkit-border-radius: 4px;
      -moz-border-radius: 4px;
      border-radius: 4px;
      border: solid 1px #20538D;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
      -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      background: #4479BA;
      color: #FFF;
      padding: 8px 12px;
      text-decoration: none;
      margin-top: 50px;
      font-size: large;
    }
    
    @media screen and (max-width: 800px) {
      .column {
        flex: 50%;
        max-width: 50%;
      }
    }
    
    @media screen and (max-width: 600px) {
      .column {
        flex: 100%;
        max-width: 100%;
      }
    }
    
    
  4. 儲存 styles.css 檔案

更新索引檔案

在程式碼編輯器中完成下列操作。

  1. 前往新 photo-gallery-app 專案目錄中的 src 目錄。
  2. 開啟 index.html 檔案。
  3. 新增 Raleway 字型,讓所有網頁都能繼承這個字型。
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
    
  4. 儲存 index.html 檔案。
  5. 儲存程式碼並檢查瀏覽器。開發伺服器執行時,您儲存時的變更會顯示在瀏覽器中。
  6. 接下來,您將建立新的獨立元件,用於傳送意見回饋及與 Jimbo 聊天。請繼續進行本程式碼研究室,進一步瞭解 Jimbo。

5. 新增獨立元件

如您目前所見,獨立元件可減少對 NgModules 的需求,進而簡化建構 Angular 應用程式的方式。在後續章節中,您將建立新的獨立元件,讓使用者能夠傳送意見回饋,並與虛擬代理人進行即時通訊。

建立新的獨立元件

如要建立這個新元件,請再次使用 Angular CLI。

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,建立名為 feedback-and-chat 的新元件。
    ng generate component feedback-and-chat --standalone
    
    下表說明指令的各個部分。

    配件

    詳細資料

    ng

    定義 Angular 架構的所有 Angular CLI 指令

    generate component

    為新元件建立鷹架

    feedback-and-chat

    元件的名稱

    --standalone

    指示 Angular 架構建立獨立元件

匯入新的獨立元件

如要使用新的獨立元件,請先將元件新增至 app.components.ts 檔案的 imports 陣列。

這是獨立元件,因此您只需將其匯入,就如同匯入模組一樣。

在程式碼編輯器中完成以下動作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 開啟 app.component.ts 檔案。
  3. 匯入新的獨立元件。
    import { FeedbackAndChatComponent } from './feedback-and-chat/feedback-and-chat.component';
    
  4. 更新元件中的匯入項目。
    imports: [CommonModule, RouterModule, FeedbackAndChatComponent],
    
    app.component.ts 檔案應符合下列程式碼範例。
    import { CommonModule } from '@angular/common';
    import { Component } from '@angular/core';
    import { RouterModule } from '@angular/router';
    import { FeedbackAndChatComponent } from './feedback-and-chat/feedback-and-chat.component';
    
    @Component({
      selector: 'app-root',
      imports: [CommonModule, RouterModule, FeedbackAndChatComponent],
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      standalone: true
    })
    export class AppComponent {
      title = 'photo-gallery-app';
    }
    
  5. 儲存 app.component.ts 檔案。

延遲載入元件

從急載模式切換為延遲載入模式,在您需要程式碼時才會傳送至用戶端。延遲載入是縮短網頁載入時間、提升效能和使用者體驗的絕佳方法。路由器會處理延遲載入作業,ngModule 和獨立元件皆是如此。

更新與應用程式元件相關聯的 HTML 範本

如要延遲載入獨立元件,請在 UI 中新增按鈕,只在使用者選取元件時啟用該元件。

在程式碼編輯器中完成下列操作。

  1. 前往新 photo-gallery-app 專案目錄中的 src/app 目錄。
  2. 開啟 app.component.html 檔案。
  3. 捲動至檔案結尾,然後新增以下程式碼範例,再關閉 article 元素。
    <a class="link_button" routerLink="feedback-and-chat">Find out more about these guys!</a>
    <router-outlet></router-outlet> 
    
  4. app.component.html 檔案應符合以下程式碼範例。
    <article>
        <h1>Above and below the Ocean</h1>
        <h2>A taste of the Australia and Galapagos Wildlife, meet my friends!</h2>
        <section>
            <section class="row">
                <div class="column">
                    <img src="/assets/49412593648_8cc3277a9c_c.jpg">
                    <img src="/assets/49413271167_22a504c3fa_w.jpg">
                    <img src="/assets/47099018614_5a68c0195a_w.jpg">
                </div>
                <div class="column">
                    <img src="/assets/41617221114_4d5473251c_w.jpg">
                    <img src="/assets/47734160411_f2b6ff8139_w.jpg"> 
                    <img src="/assets/46972303215_793d32957f_c.jpg">
                </div>
                <div class="column">
                    <img src="/assets/45811905264_be30a7ded6_w.jpg">
                    <img src="/assets/44718289960_e83c98af2b_w.jpg">
                    <img src="/assets/46025678804_fb8c47a786_w.jpg">
                </div>
            </section>
        </section> 
        <a class="link_button" routerLink="feedback-and-chat">Find out more about these guys!</a>
        <router-outlet></router-outlet>
    </article>
    
  5. 儲存 app.component.html 檔案。

設定路線

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄中的 src 目錄。
  2. 開啟 main.ts 檔案。
  3. 匯入 provideRouter 方法和路徑模組。Angular 14.2.0 版推出了新的 provideRouter 方法,可讓我們為應用程式設定一組路徑。
    import { provideRouter, Routes } from '@angular/router';
    
  4. 在匯入作業和 if 陳述式之間複製及貼上下列程式碼片段。
    const routes = [
      {
        path: 'feedback-and-chat',
        loadComponent: () => import('./app/feedback-and-chat/feedback-and-chat.component').then(c => c.FeedbackAndChatComponent),
      }
    ]
    
  5. 複製下列程式碼片段,並替換 bootstrapApplication 方法。
    bootstrapApplication(AppComponent, {
      providers: [
        provideRouter(routes)
      ]
    }).catch(err => console.error(err));
    
    main.ts 檔案應符合下列程式碼範例。
    import { enableProdMode } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { provideRouter, Routes } from '@angular/router';
    import { AppComponent } from './app/app.component';
    import { environment } from './environments/environment';
    
    const routes = [
      {
        path: 'feedback-and-chat',
        loadComponent: () => 
          import('./app/feedback-and-chat/feedback-and-chat.component').then(c => c.FeedbackAndChatComponent),
      }
    ]
    
    if (environment.production) {
      enableProdMode();
    }
    
    bootstrapApplication(AppComponent, {
      providers: [
        provideRouter(routes)
      ]
    }).catch(err => console.error(err));
    
  6. 儲存 main.ts 檔案。

使用 Chrome 開發人員工具編譯及審查

使用 Chrome 開發人員工具查看 Angular 架構如何延遲載入元件。

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,編譯及執行應用程式並開啟網路伺服器。
    ng serve
    
    您的開發伺服器應在通訊埠 4200 執行。

在瀏覽器中完成下列操作。

  1. 前往下列頁面。
    http://localhost:4200
    
  2. 開啟 Chrome 開發人員工具,然後選擇「Network」分頁標籤。
  3. 重新整理頁面,即可顯示多個檔案,但不會顯示 feedback-and-chat 元件。您的畫面應與下列螢幕截圖相符。Chrome 開發人員工具面板開啟的應用程式螢幕截圖
  4. 選取「Find out more about these guys!」按鈕,將路由導向至獨立元件。記錄檔應會指出,只有在您觸及完整路由器時,才會載入元件。向下捲動至清單結尾,確認是否已載入元件。畫面應與下列螢幕截圖相符。應用程式螢幕截圖顯示 Chrome 開發人員工具面板開啟,顯示延遲載入的元件

6. 新增表單的使用者介面

提供意見表單有三個輸入 UI 欄位,底部則有一個按鈕。三個輸入 UI 欄位為全名、寄件者電子郵件地址和留言。

如要支援 UI,請在 input 元素中新增 formControlName 屬性,並將其繫結至與三個輸入 UI 欄位相關聯的每個 contactForm 表單控制項。

將表單新增至 HTML 範本

在 UI 中新增表單,讓使用者可以提供意見。

在程式碼編輯器中完成下列操作。

  1. 前往 feedback-and-chat.component.html 檔案。
  2. 移除現有的 HTML。
  3. 複製下列程式碼範例中的 HTML。
    <article>    
        <h2>Send me a message or use the chat below to learn some cool facts of the animals in the photos</h2>
        <section class="container">
            <form ngNativeValidate [formGroup]="contactForm" (ngSubmit)="onSubmit()">
                <div class="row" *ngIf="showMsg">
                    <div class="row">
                        <p>
                            <strong>Thanks for your message!</strong>
                        </p>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="name">Full Name</label>
                    </div>
                    <div class="col-75">
                        <input type="text" id="fname" placeholder="Your name.." formControlName="fullname" required>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="lemail">Email</label>
                    </div>
                    <div class="col-75">
                        <input type="text" id="lemail" placeholder="Your email.." formControlName="email" required>
                    </div>
                </div>
                <div class="row">
                    <div class="col-25">
                        <label for="comments">Comments</label>
                    </div>
                    <div class="col-75">
                        <textarea id="subject" formControlName="comments" placeholder="Write something.." style="height:200px" required></textarea>
                    </div>
                </div>
                <div class="row">
                  <button type="submit" class="submit">Submit</button>
                </div>
            </form>
        </section>
    </article>
    
  4. 儲存 feedback-and-chat.component.html 檔案。

更新表單的樣式檔案

在程式碼編輯器中完成下列操作。

  1. 前往 feedback-and-chat.component.css 檔案。
  2. 複製並貼上以下程式碼範例中的 CSS。
    /*   Style inputs, select elements and textareas */
    input[type=text], select, textarea{
      width: 100%;
      padding: 12px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
      resize: vertical;
    }
    
    /*   Style the label to display next to the inputs */
    label {
      padding: 12px 12px 12px 0;
      display: inline-block;
    }
    
    /*   Style the submit button */
    button {
      background-color: #4479BA;
      color: white;
      padding: 12px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      float: right;
      font-size: medium;
      font-family: 'Raleway';
    }
    
    /*   Style the container */
    .container {
      border-radius: 5px;
      background-color: #f2f2f2;
      padding: 20px;
      width: 100%;
    }
    
    /*   Floating column for labels: 25% width */
    .col-25 {
      float: left;
      width: 25%;
      margin-top: 6px;
    }
    
    /*   Floating column for inputs: 75% width */
    .col-75 {
      float: left;
      width: 75%;
      margin-top: 6px;
    }
    
    /*   Clear floats after the columns */
    .row:after {
      content: "";
      display: table;
      clear: both;
    }
    
    /*   Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */
    @media screen and (max-width: 600px) {
      .col-25, .col-75, input[type=submit] {
        width: 100%;
        margin-top: 0;
      }
    }
    
  3. 儲存 feedback-and-chat.component.css 檔案。

編譯表單的 UI 更新

在指令列視窗中完成下列步驟。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,編譯及執行應用程式,並開啟網路伺服器。
    ng serve
    
    您的應用程式應無法編譯。別擔心,您需要繫結表單。
  3. 目前請先檢查下列項目。
    • 您可以使用 formGroup 屬性繫結,將 contactForm 繫結至 form 元素和 ngSubmit 事件繫結
    • FormGroup 指令會監聽 form 元素發出的提交事件。接著,FormGroup 指示詞會發出 ngSubmit 事件,您可以將該事件繫結至 onSubmit 回呼函式。
    • 在後續步驟中,您會在 feedback-and-chat.component.ts 檔案中實作 onSubmit 回呼函式
  4. 接下來,您將繫結表單。

7. 在表單中新增事件處理機制

「傳送意見回饋」表單的 UI 已完成,但缺少互動功能。透過表單處理使用者輸入內容,是許多常見應用的基礎。

在實際的情境中,您需實作商業邏輯才能完成下列動作。

  1. 從與元件相關聯的轉譯 DOM 結構中剖析使用者輸入內容。
  2. 驗證使用者的輸入內容,其中包含人機驗證 (Captcha) 或類似機制,可避免漫遊器濫發垃圾內容。
  3. 傳送電子郵件至指定的電子郵件地址。
  4. 向使用者顯示善意訊息。

在本程式碼研究室中,您只需實作下列動作。

  1. 從與元件相關聯的轉譯 DOM 結構中剖析使用者輸入內容。
  2. 向使用者顯示友善訊息。

您必須挑戰自身技能,並實踐這四項行動。

將傳送訊息表單模型新增至元件

在元件類別中建立並新增「提供意見」表單模型。表單模型會決定表單的狀態。FormBuilder 服務提供方便的方法,可用來建立 UI 控制項。

在程式碼編輯器中完成下列操作。

  1. 前往 feedback-and-chat.component.ts 檔案。
  2. @angular/forms 套件匯入 FormBuilder 服務和 ReactiveModule 模組。這項服務提供方便產生控制項的方法。在下一個步驟中,我們將使用 inject 函式,因此也需要從 @angular/core 匯入這個函式。
    import { Component, inject, OnInit } from '@angular/core';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
  3. 匯入 ReactiveFormsModule 模組。
    imports: [CommonModule,ReactiveFormsModule],
    
  4. 移除下列建構函式。
    constructor() { }
    
  5. 透過類別簽名下方的 inject 函式,插入 FormBuilder 服務。
    private formBuilder = inject(FormBuilder);
    
    使用 FormBuilder 服務的 group 方法建立表單模型,以便收集使用者的姓名、電子郵件地址和留言。
  6. 建立新的 contactForm 屬性,並使用 group 方法將其設為表單模型。表單模型包含 nameemailcomments 欄位。
    contactForm = this.formBuilder.group({
      fullname: '',
      email: '',
      comments: ''
    });
    
    定義 onSubmit 方法來處理表單。在實際情況中,onSubmit 方法可讓使用者透過傳送至指定電子郵件地址的電子郵件,向攝影師提交意見回饋訊息。在這個程式碼研究室中,您會顯示使用者輸入內容、使用 reset 方法重設表單,並顯示友善的成功訊息。
  7. 新增 onSubmit 方法,並在初始化後將 showMsg 變數設為 true
    showMsg: boolean = false;
    
    onSubmit(): void {
      console.log('Your feedback has been submitted', this.contactForm.value);
      this.showMsg = true;
      this.contactForm.reset();
    }
    
    feedback-and-chat.component.ts 檔案應符合下列程式碼範例。
    import { Component, inject, OnInit } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-feedback-and-chat',
      standalone: true,
      imports: [CommonModule, ReactiveFormsModule],
      templateUrl: './feedback-and-chat.component.html',
      styleUrls: ['./feedback-and-chat.component.css']
    })
    export class FeedbackAndChatComponent {
    
      showMsg: boolean = false;
      private formBuilder = inject(FormBuilder);
    
      contactForm = this.formBuilder.group({
        fullname: '',
        email: '',
        comments: ''
      });
    
      ngOnInit(): void {
      }
    
      onSubmit(): void {
        console.log('Your feedback has been submitted', this.contactForm.value);
        this.showMsg = true;
        this.contactForm.reset();
      }
    }
    
  8. 儲存 feedback-and-chat.component.ts 檔案。

編譯並顯示「提供意見」表單模型

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,編譯及執行應用程式,並開啟網路伺服器。
    ng serve
    
  3. 開發伺服器應在 4200 通訊埠上執行。

在瀏覽器中完成下列操作。

  1. 前往下列頁面。
    http://localhost:4200
    
  2. 開啟 Chrome 開發人員工具,然後選擇「主控台」分頁。
  3. 在「全名」、「電子郵件」和「註解」文字方塊中輸入任何值。
  4. 選取「提交」按鈕,頁面上應會顯示成功訊息。
  5. 請確認「控制台」分頁中顯示的值。您的畫面應與下列螢幕截圖相符。瀏覽器視窗,其中的控制台顯示在表單中輸入的 JSON 資料您已成功實作程式碼,將「傳送訊息」表單新增至元件 UI,並剖析使用者輸入內容。
  6. 接下來,您將嵌入聊天對話方塊,讓應用程式訪客與 Jimbo 對話。Jimbo 是一隻無尾熊,你可以從牠身上瞭解一些關於野生動物的酷炫知識。

8. 新增即時通訊對話

運用對話介面的經驗,例如 Dialogflow CX 或類似平台。Dialogflow CX 服務專員是虛擬服務專員,可處理與使用者的並行對話。這個自然語言理解模組可辨識人類語言的細微差異,並將使用者在對話期間的文字或音訊翻譯成應用程式和服務能夠理解的結構化資料。

我們已為您建立虛擬服務專員範例,在本研究室中,您需要在獨立元件中新增聊天對話,讓應用程式使用者與機器人互動。針對這項需求,您將使用 Dialogflow Messenger,這是預先建構的整合服務,可提供可自訂的對話方塊視窗。開啟後,即時通訊對話方塊會顯示在畫面右下方,並觸發服務專員的預設歡迎意圖。機器人會向使用者問候,並發起對話。

以下實作方式與使用者分享野生動物的趣聞。虛擬服務專員的其他實作方式可能會針對客戶的複雜用途 (例如客服中心的真人服務專員) 進行調整。許多公司會使用虛擬助理,做為與公司網站聯絡的主要管道。

將 Dialogflow Messenger 新增至元件

如同表單,只有在載入獨立元件時才會顯示即時通訊對話方塊。

在程式碼編輯器中完成下列操作。

  1. 前往 feedback-and-chat.component.ts 檔案。
  2. 複製下列程式碼範例中的 df-messenger 元素,並貼到頁面中的任意位置。
    <df-messenger agent-id="762af666-79f7-4527-86c5-9ca06f72c317"
                  chat-title="Chat with Jimbo!"
                  df-cx="true"
                  intent="messanger-welcome-event"
                  language-code="en"
                  location="us-central1"></df-messenger>
    
    選取 Dialogflow Messenger 整合功能時,Dialogflow 會為 df-messenger 元素產生屬性。

    屬性

    詳細資料

    服務專員 ID

    預先填入。指定 Dialogflow 代理程式的專屬 ID。

    即時通訊標題

    預先填入。指定即時通訊對話方塊頂端顯示的內容。系統會預先填入服務專員的名稱,但您應自行自訂。

    df-cx

    表示互動對象是 CX 服務專員。將值設為 true

    意圖

    指定在開啟即時通訊對話方塊時,用來觸發第一個意圖的自訂事件。

    language-code

    為第一個意圖指定預設語言代碼。

    位置

    指定要部署服務專員的區域。

  3. 儲存 feedback-and-chat.component.ts 檔案。

顯示「提供意見」表單模型

在指令列視窗中完成下列步驟。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令來編譯應用程式。
    ng serve
    
    您的應用程式應無法編譯。指令列應會顯示下列錯誤訊息。df-messenger 錯誤訊息
  3. 接著,新增自訂結構定義。

為獨立元件新增自訂結構定義

df-messanger 元素不是已知元素。這是自訂網頁元件。Angular 架構的錯誤訊息建議您將 CUSTOM_ELEMENTS_SCHEMA 新增至兩個獨立元件,以便抑制訊息。

在程式碼編輯器中完成下列操作。

  1. 前往 feedback-and-chat.component.ts 檔案。
  2. 匯入 CUSTOM_ELEMENTS_SCHEMA 結構定義。
    import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit } from '@angular/core';
    
  3. CUSTOM_ELEMENTS_SCHEMA 新增至結構定義清單。
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
    
    feedback-and-chat.component.ts 檔案應符合下列程式碼範例。
    import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
    
    @Component({
      selector: 'app-feedback-and-chat',
      standalone: true,
      imports: [CommonModule,ReactiveFormsModule],
      templateUrl: './feedback-and-chat.component.html',
      styleUrls: ['./feedback-and-chat.component.css'],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    
    ...
    
  4. df-messenger 網路元件需要 javascript,但只有在載入意見回饋和即時通訊元件時才應插入。為此,我們會在 ngOnInit() 方法中加入相關程式碼,該方法會載入啟用 元素所需的即時通訊指令碼。
    ngOnInit() {
        // Load the chat script, which activates the `<df-messenger>` element.
        const script = document.createElement('script');
        script.async = true;
        script.src = 'https://www.gstatic.com/dialogflow-console/fast/messenger-cx/bootstrap.js?v=1';
        document.head.appendChild(script);
    }
    
  5. 儲存 feedback-and-chat.component.ts 檔案。

編譯並顯示更新後的即時通訊對話方塊

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,編譯及執行應用程式,並開啟網路伺服器。
    ng serve
    
    開發伺服器應在 4200 通訊埠上執行。

在瀏覽器中完成下列操作。

  1. 前往下一頁。
    http://localhost:4200
    
    頁面底部應該會顯示即時通訊圖示。
  2. 選取圖示與 Jimbo 互動,Jimbo 會提供有趣的動物知識。應用程式顯示即時通訊視窗,以及 Messenger 機器人回應
  3. 本應用程式功能完全正常。

9. 將應用程式部署至 Google App Engine

應用程式在本機電腦上執行。本程式碼研究室的最後一個步驟,就是將程式碼部署至 Google App Engine。

如要進一步瞭解 Google App Engine,請參閱「App Engine」。

設定 Google App Engine 環境

如果已符合所有條件,請略過後續步驟並繼續部署應用程式。

  • 使用 App Engine 建立 Cloud 專案
  • 已啟用 Cloud Build API
  • 已安裝 Google Cloud CLI

完成下列操作。

  1. 登入 Gmail 或 Google Workspace 帳戶。如果沒有 Google 帳戶,請建立帳戶
  2. 請在 Cloud 控制台中啟用計費功能,以便使用 Cloud 資源和 API。詳情請參閱「建立、修改或關閉自助式 Cloud Billing 帳戶」。
  3. 建立 Google Cloud 專案,用於存放 App Engine 應用程式資源和其他 Google Cloud 資源。詳情請參閱「建立及管理專案」。
  4. 在 Cloud Console 中啟用 Cloud Build API。詳情請參閱「啟用 API 存取權」。
  5. 安裝 Google Cloud CLI 和 gcloud 指令列工具。詳情請參閱「安裝 gcloud CLI」。
  6. 初始化 Google Cloud CLI,並確認 gcloud 已設定為使用您要部署的 Google Cloud 專案。詳情請參閱「初始化 gcloud CLI」。

建構獨立應用程式

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列 Angular 指令,即可編譯及建立可用於實際工作環境的應用程式版本。
    ng build
    

正式版應用程式會在 photo-gallery-app 專案目錄的 dist 子目錄中建立。

10. 使用 Express.js 架構部署應用程式

本程式碼研究室中的範例程式碼會使用 Express.js 架構處理 HTTP 要求。您可以使用偏好的網路架構。

安裝 Express.js 架構

在指令列視窗中,完成下列操作。

  1. 輸入下列指令,安裝 Express.js 架構。
    npm install express --save
    

設定網路伺服器

在程式碼編輯器中完成以下動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 建立新的 server.js 檔案。
  3. 複製並貼上以下程式碼。
    const express = require("express");
    const path = require("path");
    
    // Running PORT is set automatically by App Engine
    const port = process.env.PORT || 3000;
    const app = express();
    
    const publicPath = path.join(__dirname, "/dist/photo-gallery-app");
    
    app.use(express.static(publicPath));
    
    app.get("*", (req, res) => {
      res.sendFile(path.join(__dirname + "/dist/photo-gallery-app/index.html"));
    });
    
    app.listen(port, () => {
      console.log(`Server is up on ${port}`);
    });
    
  4. 儲存 server.js 檔案。

附加網路伺服器

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 開啟 package.json 檔案。
  3. 修改啟動指令,以便在 server.js 檔案中執行節點。
    "name": "photo-gallery-app",
      "version": "0.0.0",
      "scripts": {
        "ng": "ng",
        "start": "node server.js",
        "build": "ng build",
        "watch": "ng build --watch --configuration development",
        "test": "ng test"
      },
    
    start 屬性是應用程式的進入點。
  4. 儲存 package.json 檔案。

設定 App Engine

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 建立新的 app.yaml 檔案。
  3. 複製並貼上以下程式碼。
    runtime: nodejs16
    service: default
    
    app.yaml 檔案中的資訊會指定 App Engine 的設定。您只需要指定執行階段和服務。
  4. 儲存 app.yaml 檔案。

更新 gcloud 忽略清單

如要確保系統不會上傳 node_modules 目錄,請建立 .gcloudignore 檔案。系統不會上傳 .gcloudignore 檔案中所列的檔案。

在程式碼編輯器中完成下列操作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 建立新的 .gcloudignore 檔案。
  3. 複製並貼上以下程式碼。
    # This file specifies files that are *not* uploaded to Google Cloud
    # using gcloud. It follows the same syntax as .gitignore, with the addition of
    # "#!include" directives (which insert the entries of the given .gitignore-style
    # file at that point).
    #
    # For more information, run:
    #   $ gcloud topic gcloudignore
    #
    .gcloudignore
    # If you would like to upload your .git directory, .gitignore file or files
    # from your .gitignore file, remove the corresponding line
    # below:
    .git
    .gitignore
    
    # Node.js dependencies:
    node_modules/
    
  4. 儲存 .gcloudignore 檔案。

初始化應用程式

在部署應用程式之前,請先透過專案初始化應用程式,然後選擇相關聯的區域。

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列指令,初始化應用程式。
    gcloud app create --project=[YOUR_PROJECT_ID]
    
  3. 按照提示,選擇 App Engine 應用程式所在的地區。

部署應用程式

在指令列視窗中,完成下列動作。

  1. 前往新的 photo-gallery-app 專案目錄。
  2. 輸入下列指令來部署應用程式。
    gcloud app deploy --project=[YOUR_PROJECT_ID]
    
  3. 在提示訊息中確認動作。gcloud 部署指令完成後,系統會顯示應用程式的網址。
  4. 輸入下列指令,在瀏覽器中開啟新分頁。
    gcloud app browse
    
    gcloud app deploy 及進入 glcoud 應用程式瀏覽的控制台輸出內容

11. 恭喜

恭喜!您已使用 Angular 14 建立範例相片庫,並成功在 App Engine 上部署。

您已嘗試使用獨立元件功能和延遲載入功能。您建立了以表單為基礎的傳送訊息功能,用於提供意見回饋和評論。您也已成功使用 Dialogflow Messenger 與 Dialogflow CX 虛擬服務專員新增即時通訊對話。太棒了!

後續步驟

現在您已完成基本應用程式,接下來可以運用下列建議加以改進。

  • 表單實際上並未傳送意見回饋,請重構表單,加入傳送電子郵件的業務邏輯。
  • 在實際情況中,您應驗證使用者輸入內容,並加入人機驗證或類似機制,避免機器人散布垃圾內容。
  • 建立新的虛擬服務專員,並瞭解如何在 Dialogflow CX 中設計對話流程

繼續實驗 Angular 架構,享受其中樂趣。

清理並刪除 Cloud 專案

您可以保留 Cloud 專案,也可以刪除專案,這樣系統就會停止對專案使用的所有資源收取費用。

在瀏覽器中完成下列操作。

  1. 登入 Gmail 或 Google Workspace 帳戶。
  2. Google Cloud 控制台中,選取「IAM & Admin Settings」(IAM 與管理設定) 按鈕。
  3. 在「IAM 與管理」頁面上,選取「管理資源」分頁標籤。
  4. 在「管理資源」頁面中,前往要刪除的專案並選取該專案。選取「刪除」按鈕,開啟對話方塊。
  5. 在對話方塊視窗中輸入專案 ID。選取「Shut down」按鈕即可刪除專案。