1. 简介
构建内容
在此 Codelab 中,您将使用 Angular v14 构建一个野生动物照片库应用。完成申请后,系统会显示一组照片,还会显示一个发送消息表单,供您与摄影师联系,以及一个聊天窗口,供您了解照片中动物的趣味知识。
您可以使用 Angular v14 和新的独立组件功能在应用中构建所有内容。
对 Angular 框架和 Angular CLI 的所有引用都反映了 Angular v14。独立组件是 Angular v14 的预览功能,因此您必须使用 Angular v14 创建一个全新的应用。独立组件提供了一种简化 Angular 应用构建方式。独立组件、独立指令和独立流水线旨在减少对 NgModules
的需求,从而简化创作体验。独立组件能够充分利用现有的 Angular 库生态系统。
这是您今天要构建的应用。
学习内容
- 如何使用 Angular CLI 为新项目构建基架
- 如何使用 Angular 独立组件简化 Angular 应用的开发
- 如何创建独立组件;即如何构建界面并添加一些业务逻辑
- 如何使用独立组件引导应用
- 如何延迟加载独立组件
- 如何使用 Dialogflow Messenger 在独立组件中嵌入聊天对话
- 如何使用 Google Cloud CLI (gcloud) 将 Angular 应用部署到 Google Cloud App Engine
所需条件
- Gmail 或 Google Workspace 账号
- 具备以下主题的基础知识
- HTML。如何创建元素。
- CSS 等。如何使用 CSS 选择器和创建样式定义文件。
- TypeScript 或 JavaScript。如何与 DOM 结构交互。
- Git 和 GitHub。如何创建分支代码库和克隆代码库。
- 命令行界面,例如
bash
或zsh
。如何浏览目录和运行命令。
2. 环境设置
设置本地环境
如需完成此 Codelab,您必须在本地计算机上安装以下软件。
- 活跃 LTS 或维护 LTS 版本的 Node.js。用于安装 Angular 框架和 Angular CLI。
节点版本
受 Angular 支持
14.15 或更高版本
支持
16.10 或更高版本
支持
18.1.0
不支持
node
命令。node -v
- 代码编辑器或 IDE。用于打开和修改文件。Visual Studio Code 或您选择的其他代码编辑器。
安装 Angular CLI
配置所有依赖项后,运行以下 npm
命令,从命令行窗口安装 Angular CLI。
npm install --global @angular/cli
如需确认您的配置是否正确,请从命令行运行以下 Angular 命令。
ng version
如果 Angular 命令成功完成,您应该会收到类似于以下屏幕截图的消息。
源代码和图片
您将从头开始创建整个应用,此 Codelab 会一步步指导您为您提供帮助。请注意,GitHub 代码库包含最终代码。如果您遇到问题,请查看最终代码和图库页面上显示的图片。
下载源代码。
- 在浏览器中,浏览以下页面。
https://github.com/angular/codelabs/tree/standalone-components
- 在命令行窗口中,创建代码库分支并克隆代码库。
在下一步中,构建您的图库应用。
3. 创建新应用
如需创建初始起始应用,请完成以下操作。
使用 Angular CLI 创建新的工作区。如需详细了解 Angular CLI 和 Angular 框架,请访问 angular.io。
创建新项目
在命令行窗口中,完成以下操作。
- 输入以下 Angular 命令,创建一个名为
photo-gallery-app
的新 Angular 项目。ng new photo-gallery-app
- 在每个提示处,接受默认选项。Angular 框架会安装所需的软件包和依赖项。此过程可能需要几分钟时间。
Angular CLI 完成后,您将获得一个新的 Angular 工作区和一个简单的随时可运行的应用。
您的新应用的结构与标准 Angular 应用类似。在此 Codelab 中,新应用中的 NgModule 是多余的。
移除应用模块
如需移除应用模块,请完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 删除
app.module.ts
文件。
删除应用模块后,您的应用中将没有任何模块。您的应用只有一个组件,即应用组件。您必须将该组件声明为独立组件。
声明独立组件
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 打开
app.component.ts
文件。 - 将以下参数和值添加到您的装饰器列表中。
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'; }
- 保存
app.component.ts
文件。
编译新的独立应用
在命令行窗口中,完成以下操作。
- 前往新的
photo-gallery-app
项目目录 - 输入以下 Angular 命令以编译新应用。
ng serve
您的应用应该无法编译。不用担心,您只需再修复几个问题。
使用 bootstrapApplication API
如需允许您的应用在没有 NgModule
的情况下运行,您必须使用 bootstrapApplication
API 将独立组件用作根组件。
移除对应用模块的引用
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src
目录 - 打开
main.ts
文件。 - 移除以下导入代码,因为您不再拥有应用模块。
import { AppModule } from './app/app.module'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
- 由于您不再有应用模块,因此请移除以下引导加载代码。
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 组件
在代码编辑器中,完成以下操作。
- 进入新的
photo-gallery-app
项目目录中的src
目录。 - 打开
main.ts
文件。 - 从
@angular/platform-browser
服务导入bootstrapApplication
组件。import { bootstrapApplication } from '@angular/platform-browser';
- 添加以下代码以引导您的应用。
bootstrapApplication(AppComponent).catch(err => console.error(err));
- 导入组件和所需的库。
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));
添加了路由器和常见模块
如需使用 Router 和其他常见模块功能,您必须将每个模块直接导入到组件中。
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 打开
app.component.ts
文件。 - 将所需的模块导入到组件中。
import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router';
- 在组件中添加导入项。
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'; }
- 保存
app.component.ts
文件。
编译并运行新的独立应用
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译和运行应用并打开 Web 服务器。您可能需要先关闭 IDE,然后才能运行应用以移除所有编译错误。
ng serve
您的开发服务器应该在端口 4200
上运行。之前的所有错误都应已消失,编译也应成功。非常棒!您已成功创建一个无模块且使用独立组件运行的 Angular 应用。
- 接下来,您将美化应用,以便显示一些照片。
4. 显示照片
您的新应用设计为照片库,并且应该会显示一些照片。
组件是 Angular 应用的核心构建块。组件有 3 个主要方面。
- 模板的 HTML 文件
- 样式的 CSS 文件
- 用于定义应用行为的 TypeScript 文件
将照片移至您的应用
这些照片会在您之前从 GitHub 下载的应用中提供。
- 前往 GitHub 项目的
src/assets
目录。 - 将这些文件复制并粘贴到
photo-gallery-app
项目目录的analogue
目录中。
创建 HTML 模板
app.component.html
文件是与 AppComponent
组件关联的 HTML 模板文件。
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 打开
app.component.html
文件。 - 删除所有现有的 HTML。
- 复制并粘贴以下代码示例中的 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
- 保存
app.component.html
文件。
创建样式定义文件
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src
目录。 - 打开
styles.css
文件。 - 复制以下代码示例中的 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%; } }
- 保存
styles.css
文件
更新索引文件
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src
目录。 - 打开
index.html
文件。 - 添加
Raleway
字体,以允许所有网页继承该字体。<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
- 保存
index.html
文件。 - 保存代码,然后检查浏览器。开发服务器运行时,您保存更改后,这些更改会反映在浏览器中。
- 接下来,您将创建一个新的独立组件,用于发送反馈和与 Jimbo 聊天。继续完成本 Codelab,详细了解 Jimbo。
5. 添加新的独立组件
如您在前面所看到的,通过减少对 NgModule 的需求,独立组件提供了一种简化构建 Angular 应用的方法。在以下部分中,您将创建一个新的独立组件,让用户能够发送反馈和与虚拟客服人员聊天。
创建新的独立组件
如需创建这个新组件,请再次使用 Angular CLI。
在命令行窗口中,完成以下操作。
- 前往新的
photo-gallery-app
项目目录。 - 输入以下 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
数组。
这是一个独立组件,因此您只需像导入模块一样导入它即可。
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 打开
app.component.ts
文件。 - 导入新的独立组件。
import { FeedbackAndChatComponent } from './feedback-and-chat/feedback-and-chat.component';
- 更新组件中的 import 语句。
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'; }
- 保存
app.component.ts
文件。
延迟加载组件
从提前加载范式切换到延迟加载范式,在这种范式中,系统不会在您需要之前将代码发送到客户端。延迟加载是一种非常有效的方法,可缩短网页加载时间、提升性能并改善用户体验。路由器会处理延迟加载,对于 ngModule
和独立组件,此操作是相同的。
更新与应用组件关联的 HTML 模板
如需延迟加载独立组件,请向界面添加一个按钮,该按钮仅在用户选择该组件时才会激活该组件。
在代码编辑器中,完成以下操作。
- 前往新
photo-gallery-app
项目目录中的src/app
目录。 - 打开
app.component.html
文件。 - 滚动到文件末尾,在关闭
article
元素之前添加以下代码示例。<a class="link_button" routerLink="feedback-and-chat">Find out more about these guys!</a> <router-outlet></router-outlet>
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>
- 保存
app.component.html
文件。
配置路线
在代码编辑器中,完成以下操作。
- 进入新的
photo-gallery-app
项目目录中的src
目录。 - 打开
main.ts
文件 - 导入
provideRouter
方法和 Routes 模块。Angular v 14.2.0 引入了新的 provideRouter 方法,可让我们为应用配置一组路由。import { provideRouter, Routes } from '@angular/router';
- 复制以下代码段并将其粘贴到导入语句和
if
语句之间。const routes = [ { path: 'feedback-and-chat', loadComponent: () => import('./app/feedback-and-chat/feedback-and-chat.component').then(c => c.FeedbackAndChatComponent), } ]
- 复制并粘贴以下代码段,然后替换
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));
- 保存
main.ts
文件。
使用 Chrome 开发者工具进行编译和检查
使用 Chrome 开发者工具查看 Angular 框架如何延迟加载组件。
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译和运行应用并打开 Web 服务器。
您的开发服务器应在端口ng serve
4200
上运行。
在浏览器中,完成以下操作。
- 前往以下页面。
http://localhost:4200
- 打开 Chrome 开发者工具,然后选择网络标签页。
- 刷新页面以显示多个文件,但不显示
feedback-and-chat
组件。您的屏幕应与以下屏幕截图一致。 - 选择 Find out more about these guys! 按钮以转到独立组件。日志应指明,只有在您访问完整路由器时,该组件才会加载。向下滚动到列表底部,检查组件是否已加载。您的屏幕应与以下屏幕截图一致。
6. 为表单添加界面
“发送反馈”表单包含三个输入界面字段和一个底部按钮。三个输入界面字段分别是全名、发件人电子邮件地址和备注。
如需支持该界面,请在 input
元素中添加 formControlName
属性,将其绑定到与三个输入界面字段各自关联的每个 contactForm
表单控件。
将表单添加到 HTML 模板
向界面添加表单,以便用户发送反馈。
在代码编辑器中,完成以下操作。
- 找到
feedback-and-chat.component.html
文件。 - 移除现有的 HTML。
- 复制并粘贴以下代码示例中的 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>
- 保存
feedback-and-chat.component.html
文件。
更新表单的样式文件
在代码编辑器中,完成以下操作。
- 找到
feedback-and-chat.component.css
文件。 - 复制以下代码示例中的 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; } }
- 保存
feedback-and-chat.component.css
文件。
编译表单的界面更新
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译和运行应用,然后打开网络服务器。
您的应用应无法编译。别担心,您需要绑定表单。ng serve
- 目前,请查看以下内容。
- 您可以使用
formGroup
属性绑定将contactForm
绑定到form
元素和ngSubmit
事件绑定 FormGroup
指令会监听form
元素发出的提交事件。然后,FormGroup
指令会发出一个ngSubmit
事件,您可以将该事件绑定到onSubmit
回调函数。- 在后面的步骤中,您将在
feedback-and-chat.component.ts
文件中实现onSubmit
回调函数
- 您可以使用
- 接下来,您需要绑定表单。
7. 向表单添加事件处理
发送反馈表单的界面已完成,但缺少互动。使用表单处理用户输入是许多常见应用的基石。
在实际场景中,您需要实现业务逻辑来完成以下操作。
- 从与该组件相关联的已渲染 DOM 结构中解析用户输入。
- 验证用户输入,包括使用人机识别系统或类似机制来避免聊天机器人发送垃圾内容。
- 向指定的电子邮件地址发送电子邮件。
- 向用户显示友好的消息。
在此 Codelab 中,您只需实现以下操作。
- 从与该组件相关联的已渲染 DOM 结构中解析用户输入。
- 向用户显示友好的消息。
您应该挑战自己的技能,实现所有四项操作。
将发送消息表单模型添加到组件
在组件类中创建并添加“发送反馈”表单模型。表单模型决定了表单的状态。FormBuilder
服务提供了便捷的方法来创建界面控件。
在代码编辑器中,完成以下操作。
- 找到
feedback-and-chat.component.ts
文件。 - 从
@angular/forms
软件包导入FormBuilder
服务和ReactiveModule
模块。此服务提供了生成控件的便捷方法。在下一步中,我们将利用inject
函数,因此还需要从@angular/core
导入该函数。import { Component, inject, OnInit } from '@angular/core'; import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
- 导入
ReactiveFormsModule
模块。imports: [CommonModule,ReactiveFormsModule],
- 移除了以下构造函数。
constructor() { }
- 通过类签名下方的
inject
函数注入FormBuilder
服务。 使用private formBuilder = inject(FormBuilder);
FormBuilder
服务中的group
方法创建表单模型,以便收集用户的姓名、电子邮件地址和评论。 - 创建新的
contactForm
属性,并使用group
方法将其设置为表单模型。表单模型包含name
、email
和comments
字段。 定义一个contactForm = this.formBuilder.group({ fullname: '', email: '', comments: '' });
onSubmit
方法来处理表单。在实际场景中,onSubmit
方法允许用户使用发送到指定电子邮件地址的电子邮件向摄影师提交反馈消息。在此 Codelab 中,您将显示用户输入,使用reset
方法重置表单,并显示方便用户使用的成功消息。 - 添加新的
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(); } }
- 保存
feedback-and-chat.component.ts
文件。
编译并显示“发送反馈”表单模型
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译和运行应用并打开 Web 服务器。
ng serve
- 您的开发服务器应在端口
4200
上运行。
在浏览器中,完成以下操作。
- 前往以下页面。
http://localhost:4200
- 打开 Chrome 开发者工具,然后选择控制台标签页。
- 在全名、电子邮件地址和备注文本框中输入任意值。
- 选择 Submit 按钮。页面上应会显示一条成功消息。
- 验证 Console 标签页中显示的值。您的屏幕应与以下屏幕截图一致。您已成功实现代码,将发送消息表单添加到组件界面并解析用户输入。
- 接下来,您需要嵌入一个聊天对话框,以便应用访问者与 Jimbo 交谈。Jimbo 是一只考拉熊,可以向它了解一些关于野生动物的趣事。
8. 添加聊天对话
利用对话界面(例如 Dialogflow CX 或类似平台)的经验。Dialogflow CX 代理是一种能够处理人际对话的虚拟客服。它是一种自然语言理解模块,能够识别人类语言的细微差别,将对话过程中的最终用户文本或音频转换为应用和服务能够理解的结构化数据。
系统已为您创建示例虚拟客服供您使用。在本实验中,您需要做的是向独立组件添加聊天对话框,让应用用户与聊天机器人互动。为满足此要求,您将利用 Dialogflow Messenger,这是一个预构建的集成,可提供可自定义的对话框窗口。打开时,聊天对话框会显示在屏幕右下角,并触发客服人员的默认欢迎 intent。聊天机器人问候用户并发起对话。
以下实现会与用户分享有关野生动物的有趣知识。虚拟客服的其他实现可能适用于客户的复杂用例(例如人工呼叫中心客服人员)。许多公司都将虚拟客服人员作为与公司网站沟通的主要渠道。
将 Dialogflow Messenger 添加到您的组件
与表单一样,聊天对话框也应仅在加载独立组件时显示。
在代码编辑器中,完成以下操作。
- 找到
feedback-and-chat.component.ts
文件。 - 将以下代码示例中的
df-messenger
元素复制并粘贴到页面的任意位置。 当您选择 Dialogflow Messenger 集成时,Dialogflow 会为<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>
df-messenger
元素生成属性。属性
详细信息
agent-id
预先填充。指定 Dialogflow 代理的唯一标识符。
chat-title
预先填充。指定要在聊天对话框顶部显示的内容。最初会使用代理的名称进行预填充,但您应该自定义该名称。
df-cx
表示与 CX 代理互动。将值设置为
true
。intent
指定用于在聊天对话框打开时触发第一个 intent 的自定义事件。
language-code
指定第一个 intent 的默认语言代码。
地理位置
指定您要部署代理的区域。
- 保存
feedback-and-chat.component.ts
文件。
显示“发送反馈”表单模型
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译应用。
您的应用应该无法编译。命令行应显示以下错误消息。ng serve
- 接下来,添加自定义架构。
向独立组件添加自定义架构
df-messanger
元素不是已知元素。它是一种自定义 Web 组件。Angular 框架中的错误消息提示您必须向这两个独立组件添加 CUSTOM_ELEMENTS_SCHEMA,才能抑制该消息。
在代码编辑器中,完成以下操作。
- 找到
feedback-and-chat.component.ts
文件。 - 导入
CUSTOM_ELEMENTS_SCHEMA
架构。import { Component, CUSTOM_ELEMENTS_SCHEMA, inject, OnInit } from '@angular/core';
- 将
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] }) ...
- df-messanger Web 组件需要 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); }
- 保存
feedback-and-chat.component.ts
文件。
编译并显示更新后的聊天对话框
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令以编译和运行应用并打开 Web 服务器。
您的开发服务器应在端口ng serve
4200
上运行。
在浏览器中,完成以下操作。
- 前往以下页面。
页面底部应会显示一个聊天图标。http://localhost:4200
- 选择该图标即可与 Jimbo 互动。Jimbo 会提供有趣的动物知识。
- 应用可以完全正常运行。
9. 将应用部署到 Google App Engine
应用在您的机器本地运行。在此 Codelab 的下一步和最后一步中,您要做的是将其部署到 Google App Engine。
如需详细了解 Google App Engine,请参阅 App Engine。
为 Google App Engine 设置环境
如果您已满足以下所有条件,请跳过后续步骤,继续部署应用。
- 使用 App Engine 创建了 Cloud 项目
- 启用了 Cloud Build API
- 安装了 Google Cloud CLI
完成以下操作。
- 登录您的 Gmail 或 Google Workspace 账号。如果您还没有 Google 账号,请创建 Google 账号。
- 在 Cloud 控制台中启用结算功能,以便您使用 Cloud 资源和 API。如需了解详情,请参阅创建、修改或关闭自助 Cloud Billing 账号。
- 创建一个 Google Cloud 项目来存放您的 App Engine 应用资源和其他 Google Cloud 资源。如需了解详情,请参阅创建和管理项目。
- 在 Cloud 控制台中启用 Cloud Build API。如需了解详情,请参阅启用对 API 的访问权限。
- 安装 Google Cloud CLI 和 gcloud 命令行工具。如需了解详情,请参阅安装 gcloud CLI。
- 初始化 Google Cloud CLI,并确保 gcloud 已配置为使用您要部署到的 Google Cloud 项目。如需了解详情,请参阅初始化 gcloud CLI。
构建独立应用
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下 Angular 命令,编译并创建可用于生产环境的应用版本。
ng build
可在 photo-gallery-app
项目目录的 dist
子目录下创建可正式投入使用的应用版本。
10. 使用 Express.js 框架部署应用
本 Codelab 中的示例代码使用 Express.js 框架来处理 HTTP 请求。您可以使用自己偏好的 Web 框架。
安装 Express.js 框架
在命令行窗口中,完成以下操作。
- 输入以下命令以安装 Express.js 框架。
npm install express --save
配置网络服务器
在代码编辑器中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 创建一个新的
server.js
文件。 - 复制并粘贴以下代码。
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}`); });
- 保存
server.js
文件。
连接 Web 服务器
在代码编辑器中,完成以下操作。
- 前往新的
photo-gallery-app
项目目录。 - 打开
package.json
文件。 - 修改启动命令以在
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
属性是应用的入口点。 - 保存
package.json
文件。
配置 App Engine
在代码编辑器中,完成以下操作。
- 前往新的
photo-gallery-app
项目目录。 - 创建一个新的
app.yaml
文件。 - 复制并粘贴以下代码。
runtime: nodejs16 service: default
app.yaml
文件中的信息指定了 App Engine 的配置。您只需指定运行时和服务即可。 - 保存
app.yaml
文件。
更新 gcloud 忽略列表
为确保系统不会上传您的 node_modules
目录,请创建一个 .gcloudignore
文件。系统不会上传 .gcloudignore
文件中列出的文件。
在代码编辑器中,完成以下操作。
- 前往新的
photo-gallery-app
项目目录。 - 创建一个新的
.gcloudignore
文件。 - 复制并粘贴以下代码。
# 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/
- 保存
.gcloudignore
文件。
初始化应用
在部署应用之前,请使用您的项目初始化该应用,并选择关联的区域。
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下命令以初始化应用。
gcloud app create --project=[YOUR_PROJECT_ID]
- 系统提示时,选择您希望自己的 App Engine 应用所在的区域。
部署应用
在命令行窗口中,完成以下操作。
- 转到新的
photo-gallery-app
项目目录。 - 输入以下命令以部署应用。
gcloud app deploy --project=[YOUR_PROJECT_ID]
- 在提示符处确认操作。gcloud 部署命令成功完成后,它会显示一个网址,用于访问您的应用。
- 输入以下命令,在浏览器中打开一个新标签页。
gcloud app browse
11. 恭喜
恭喜!您使用 Angular v14 创建了一个示例照片库,并成功在 App Engine 上部署了该库。
您已尝试使用独立组件功能和延迟加载。您构建了一个基于表单的消息发送功能,以便用户提供反馈和评论。您还成功使用 Dialogflow Messenger 添加了与 Dialogflow CX 虚拟客服人员的聊天对话。非常棒。
后续步骤
现在,您已完成基本应用,接下来可以使用以下想法对其进行改进。
- 该表单实际上不会发送反馈,请对其进行重构,以添加发送电子邮件的业务逻辑。
- 在实际场景中,您应该验证用户输入,并添加人机识别系统或类似机制来避免机器人发送垃圾内容
- 创建新的客服,并了解如何在 Dialogflow CX 中设计对话流
继续尝试 Angular 框架,享受其中的乐趣。
清理和删除您的 Cloud 项目
您可以保留自己的 Cloud 项目,也可以将其删除,以便停止对该项目中使用的所有资源计费。
在浏览器中,完成以下操作。