揭开Angular 7的神秘面纱

Angular 将服务器端开发领域的一些最佳实践用于增强浏览器中的HTML,为更加简便地构建富应用程序(rich
application)打下良好基础。Angular 应用程序围绕模型-视图-控制器(Model-View-Controller,MVC)设计模式构建,该
模式的重点在于创建具有如下特点的应用程序:
● 可扩展:一旦理解Angular 的基本原理,即便是复杂的Angular 应用程序,也很容易弄明白其运行方式,而
这意味着可以轻易地改进应用程序,为用户创建新的有用功能。
● 可维护:Angular 应用程序易于调试和修复,这意味着长期维护工作得以简化。
● 可测试:Angular 对单元测试和端到端测试的支持都非常好,这意味着可以先于用户发现并修复缺陷。
● 兼容标准:Angular 建立在Web 浏览器的固有功能上,但是它能实现的功能并未受到这些固有功能的限制,
而是能够创建可兼容标准的Web 应用程序,能够利用最新功能(如HTML5 API)和流行的工具与框架。
Angular 是由Google 赞助和维护的开源JavaScript 库。它已用于一些最大和最复杂的Web 应用程序。本书将展
示在自己的项目中充分利用Angular 所需要知道的一切。
1.1 需要了解什么
在阅读本书之前,读者应该熟悉Web 开发的基础知识,了解HTML 和CSS 的工作原理,最好熟悉JavaScript。
如果对这些细节不是非常清楚,那么本书将在第4~6 章中温习一下如何使用HTML、CSS 和JavaScript。但是本书
不会给出HTML 元素和CSS 属性的全面参考。一本关于Angular 的书不可能涵盖HTML 的方方面面。
1.2 本书结构
本书分为三个部分,每部分涵盖一组相关的主题。
1.2.1 第Ⅰ部分:Angular 基础知识
本书的第Ⅰ部分为阅读本书其余部分提供了准备信息。它包括本章内容,回顾了一些关键技术的基本知识,包
括HTML、CSS 和TypeScript(JavaScript 的一个超集,用于Angular 开发)。这部分还将展示如何构建第一个Angular
应用程序,并引导完成构建更真实的应用程序(名为SportsStore)的过程。
1.2.2 第Ⅱ部分:Angular 详解
本书的第Ⅱ部分介绍Angular 为构建应用程序提供的构造块,依次描述所有这些构造块。Angular 包含很多内置
的功能,这部分将深入描述这些功能,此外Angular 还提供丰富的自定义选项,而这部分也将展示所有这些功能。
1.2.3 第Ⅲ部分:Angular 高级功能
本书的第Ⅲ部分介绍如何使用高级功能来创建更复杂、可扩展的应用程序。这部分演示如何在Angular 应用程
序中进行异步HTTP 请求,如何使用URL 路由在应用程序中导航,以及在应用程序的状态发生变化时如何使HTML
元素具有动画效果。

1.3 大量示例
本书包含大量示例。学习Angular 的最好方法就是通过示例,本书将尽可能多的示例打包进来。为使本书中的
示例尽可能多,本书采用一个简单的约定来避免反复地列出文件的内容。当在某一章中首次使用一个文件时,将列
出该文件的完整内容,如代码清单1-1 所示。代码清单的标题中将包含文件的名称,以及应该在哪个文件夹中创建
该文件。更改代码时,将以粗体显示修改过的语句。
代码清单1-1 完整的示例文档
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { ProductComponent } from "./component";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { PaAttrDirective } from "./attr.directive";
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule],
declarations: [ProductComponent, PaAttrDirective],
bootstrap: [ProductComponent]
})
export class AppModule { }
代码清单1-1 摘自第15 章。这里暂不关注它的具体作用,只需要注意,这是一个完整清单,显示了文件的所有
内容。对同一个文件进行一系列修改,或对大文件进行较小修改时,只展示发生改变的元素,以创建部分代码清单。
部分代码清单的特征就是以英文省略号(...)开始和结尾,如代码清单1-2 所示。
代码清单1-2 部分代码清单
...
<table class="table table-sm table-bordered table-striped">
<tr><th></th><th>Name</th><th>Category</th><th>Price</th></tr>
<tr *ngFor="let item of getProducts(); let i = index" pa-attr>
<td>{ {i + 1}}</td>
<td>{ {item.name}}</td>
<td pa-attr pa-attr-class="bg-warning">{ {item.category}}</td>
<td pa-attr pa-attr-class="bg-info">{ {item.price}}</td>
</tr>
</table>
...
代码清单1-2 也是摘自第15 章的后续代码清单。可以看到,这里只显示了table 元素及其内容,并且突出显示
了一些语句。希望借此引起读者的注意,关注示例的这一部分,以说明所描述的功能或技术。某些情况下,需要对
同一个文件的不同部分进行更改,此时为简洁起见,需要省略一些元素或语句,如代码清单1-3 所示。
代码清单1-3 为简洁起见而省略部分语句
import { ApplicationRef, Component } from "@angular/core";
import { Model } from "./repository.model";
import { Product } from "./product.model";
import { ProductFormGroup } from "./form.model";
@Component({
selector: "app",
templateUrl: "app/template.html"
})
export class ProductComponent {
model: Model = new Model();
form: ProductFormGroup = new ProductFormGroup();
// ...other members omitted for brevity...
showTable: boolean = true;
}
利用这个约定可在本书中放入更多示例,但这也意味着很难定位某项技术。为此,在第Ⅱ部分和第Ⅲ部分中描
述Angular 特性的所有章都从一个内容摘要表格开始,描述该章包含的技术以及演示如何使用它们的代码清单。1.4 获取示例代码
可以从https://github.com/Apress/pro-angular-6/tree/master/Update%20for%20Angular%207 下载本书所有章的示例
项目。这些示例项目都是针对Angular 7 更新的代码,可以免费下载,其中包含用来重新创建示例需要的所有支持资
源,这样就不必辛苦敲入这些代码。虽然不是一定要下载这些代码,但这是对示例进行实验的最简单方法。
请读者注意,本书对应的英文书籍是Pro Angular 6。在翻译期间,Angular 升级到Angular 7,因此本书的一部
分代码也随之更新。由于Angular 7 丢弃了Angular 6 的个别功能,因此中文书籍特别更新了代码清单14-26、14-27、
14-28、15-1、15-2、15-4、15-6、15-21、16-15、16-17、17-14、17-15、17-22、17-24、17-25、19-14、19-27、20-26、
20-27、20-30。删除了英文书中的代码清单15-19。
如果读者想要查看Angular 6 对应的代码,可访问http://github.com/Apress/pro-angular-6。
读者也可扫描本书封底的二维码获取代码。但请注意,由于代码时常更新,要获取完整详明的代码,请访问上
述网址下载。
1.5 如何搭建开发环境
第2 章通过创建一个简单的应用程序来介绍Angular,在介绍过程中,将说明如何建立使用Angular 的开发环境。
1.6 联系作者
如果在运行本章中示例代码的过程中遇到问题, 或者发现书中存在问题, 请发电子邮件到
[email protected],作者将竭尽所能提供帮助。
1.7 本章小结
本章概述了本书的内容和结构。学习Angular 开发的最佳方法就是通过示例,因此,下一章将直奔主题,展示
如何设置开发环境,并使用该环境创建第一个Angular 应用程序。

第2 章
第一个Angular 应用程序

开始使用Angular 的最佳方式就是动手创建一个Web 应用程序。本章将展示如何搭建开发环境,并解释创建基
本Web 应用程序的过程:从静态的功能模拟开始,然后使用Angular 功能创建一个简单的动态Web 应用程序。在第
7~10 章中,将展示如何创建一个更复杂、更真实的Angular 应用程序,但现在只需要一个简单的例子就足以演示
Angular 应用程序的主要组成部分,并为本书这部分的其他章搭建好开发环境。
如果未能理解本章的所有内容,也不必担心。Angular 的学习曲线比较陡峭,因此本章的目的只是介绍Angular
开发的基本流程,以了解各个部分之间的关系。虽然现在不会立即明白这些方面,但是当读完这本书时,就会明白
本章讲解的每个步骤以及其他方面。
2.1 准备开发环境
要进行Angular 开发,就需要做一些准备工作。下面的几节将介绍如何设置并准备好创建第一个项目。很多流
行的开发工具都对Angular 提供了很好的支持,因此可以选择自己最喜欢的一款开发工具。
2.1.1 安装Node.js
许多用于Angular 开发的工具都依赖Node.js(也称为Node),Node.js 创建于2009 年,为采用JavaScript 编写服
务器端应用程序提供了一个简单而高效的运行库。Node.js 基于Chrome 浏览器中使用的JavaScript 引擎,提供了一
个在浏览器环境之外执行JavaScript 代码的API。
虽然作为一款应用程序服务器,Node.js 已经取得了成功,但是本书之所以提到Node.js,是因为它为新一代跨
平台开发和构建工具提供了基础。由于Node.js 团队做出的一些精妙的设计决策以及Chrome JavaScript 运行库提供
的跨平台支持,人们发现它可用来编写开发工具。简而言之,Node.js 已经成为Web 应用程序开发的必备工具。
务必确保下载的Node.js 版本与本书中使用的相同。尽管Node.js 相对稳定,但是API 仍然会不时地发生重大变
更,这样可能会导致本书中的示例无法正常运行。
本书使用的版本是8.11.3,这是本书写作时的长期支持(Long Term Support,LTS)版本。当阅读本书时,Node.js
可能会有更新的版本,但是为了正常运行本书中的例子,应该坚持使用8.11.3 版本。可从https://nodejs.org/dist/v8.11.3
获取8.11.3 版本的完整系列,包括针对Windows 和macOS 的安装程序以及针对其他平台的二进制软件包。
安装Node.js 时,务必选择正确的选项,将Node.js 可执行文件添加到路径(Path 环境变量)中。安装完成后,运
行以下命令:
node -v
如果安装过程按照预期进行,就会显示以下版本号:
V8.11.3
Node.js 安装程序包含了Node 包管理器(Node Package Manager,NPM),用于管理项目中的包。运行以下命令以
确保NPM 正常工作:
npm -v如果一切正常工作,就会看到以下版本号:
5.6.0
2.1.2 安装angular-cli 包
angular-cli 包已经成为开发过程中创建和管理Angular 项目的标准方法。本书的第1 版演示了如何从头开始搭建
Angular 项目,这是一个冗长且容易出错的过程,而angular-cli 简化了这个过程。要安装angular-cli 包,请打开一个
新的命令提示符并运行以下命令:
npm install --global @angular/[email protected]
注意,global 参数前有两个连字符。如果使用Linux 或macOS,则需要使用sudo,如下所示:
sudo npm install --global @angular/[email protected]
2.1.3 安装Git
需要Git 版本控制工具来管理Angular 开发所需的一些软件包。如果正在使用Windows 或macOS,请从
https://git-scm.com/downloads 下载并运行安装程序。在macOS 上,可能需要更改安全设置,才能打开尚未由开发者
签署的安装程序。
大多数Linux 发行版已经安装了Git。如果要安装最新版本,请访问https://git-scm.com/download/linux,了解发
行版的安装说明。例如,对于Ubuntu(这是我使用的Linux 发行版),使用以下命令:
sudo apt-get install git
完成安装后,打开一个新的命令提示符,运行以下命令,来检查Git 是否已安装并可用:
git --version
此命令输出已安装的Git 软件包的版本。在撰写本书时,Git for Windows 和Git for Linux 的最新版本为2.17,
Git for macOS 的最新版本为2.16.3。
2.1.4 安装编辑器
由于程序员使用的任何编辑器都可以用于从事Angular 开发,因此可供选择的编辑器非常多。有些编辑器对
Angular 提供增强的支持,包括关键字高亮显示和良好的工具集成。如果还没有确定Web 应用程序开发的首选编辑
器,那么表2-1 介绍了一些常见选项,以供参考。本书并不依赖任何具体的编辑器,你应该使用自己喜欢的编辑器。
表2-1 支持Angular 开发的常见编辑器
名称 描述
Sublime Text Sublime Text 是一款商业跨平台编辑器,借助软件包可支持大多数编程语言、框架和平台。详见
www.sublimetext.com
Atom Atom 是一款免费、开源的跨平台编辑器,特别强调自定义和可扩展性。详见atom.io
Brackets Brackets 是由Adobe 开发的免费开源编辑器。详见bracket.io
WebStorm WebStorm 是一款付费的跨平台编辑器,集成了许多工具,开发者不必在开发过程中使用命令行。详见
www.jetbrains.com/webstorm
Visual Studio Code 是微软提供的开源的、跨平台编辑器,重点强调可扩展性,详见code.visualstudio.com
Visual Studio Visual Studio 是微软的旗舰开发工具。有免费的和商业的版本可供使用,它还附带了许多与Microsoft 生
态系统集成的工具
在选择编辑器时,最重要的考虑之一是能够过滤项目的内容,以便专注于一部分文件。Angular 项目可能有很
多文件,许多文件都有相似的名称,因此能够查找和编辑正确的文件至关重要。编辑器可以通过不同的方式实现这种聚焦功能,具体方法有两种:显示文件列表,可以打开这些文件进行编辑;或者将具有特定扩展名的文件排除
在外。
2.1.5 安装浏览器
最后一项选择是浏览器,在开发过程中需要使用浏览器检查代码是否按照预期运行。所有最新的浏览器都为开
发者提供了良好的支持,并能很好地运行Angular。本书一直使用谷歌Chrome,这也是推荐使用的浏览器。
2.2 创建并准备项目
在安装Node.js、angular-cli、编辑器和浏览器之后,就具备了开始开发之旅的基础。
2.2.1 创建项目
要创建项目,请选择一个方便的位置,并使用命令提示符来运行以下命令,以创建一个名为todo 的新项目:
ng new todo
可在以上命令的末尾加上--default 参数,以便使用默认配置创建项目。ng 命令由angular-cli 包提供,ng new 启
动一个新项目。在安装过程中将创建一个名为todo 的文件夹,其中包含启动Angular 开发所需的所有配置文件,启
动开发的一些占位符文件以及开发、运行和部署Angular 应用程序所需的NPM 软件包。NPM 软件包的数量非常多,
这意味着项目的创建可能需要一段时间。
2.2.2 添加Bootstrap CSS 包
ng new 命令创建的项目几乎包含了本章所需的所有内容。但没有包含Bootstrap CSS 包,本书使用它来样式化
HTML 内容。运行以下命令,导航到ng new 命令创建的todo 文件夹,并将Bootstrap 包添加到项目中:
cd todo
npm install [email protected]
要配置Angular 开发工具来使用Bootstrap CSS 文件,请将代码清单2-1 所示的条目添加到angular.json 文件的styles部分,该文件在创建项目时由ng new 命令添加到todo 文件夹。
代码清单2-1 在todo 文件夹的angular.json 文件中配置CSS
...
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"todo": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/todo",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css","node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": []
},
...
如第11 章所述,angular.json 文件用于配置项目工具,代码清单中显示的语句将Bootstrap CSS 文件合并到项目
中,以便将其包含在发送到浏览器的内容中。
2.2.3 启动开发工具
一切就绪,现在是测试Angular 开发工具的时候了。在todo 文件夹中运行以下命令:
ng serve --port 3000 --open
该命令启动Angular 开发工具,这些工具会执行一个初始的构建过程,为开发会话准备应用程序。这个过程需
要一些时间,输出如下:
** Angular Live Development Server is listening on localhost:3000, open your browser on
http://localhost:3000/ **
Hash: ebb64e6046efff317389
Time: 6767ms
chunk {main} main.js, main.js.map (main) 10.8 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 227 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 5.22 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 15.7 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.06 MB [initial] [rendered]
[wdm]: Compiled successfully.
如果输出略微不同,只要在准备工作完成后看到“compiled successfully”消息,就不必担心。几秒钟后,将启
动一个新的浏览器窗口,如图2-1 所示,其中显示了创建项目时添加到项目中的占位符内容。


图2-1 HTML 占位符内容
2.2.4 编辑HTML 文件
下面首先删除项目创建时添加到项目中的占位符内容,这样就可以从包含静态内容的HTML 文件开始,稍后使
用Angular 对其进行增强。编辑todo/src 文件夹中的index.html 文件,将内容替换为代码清单2-2 所示的内容。

代码清单2-2 src 文件夹中的index.html 文件的内容
<!DOCTYPE html>
<html>
<head>
<title>ToDo</title>
<meta charset="utf-8" />
</head>
<body class="m-1 p-1">
<h3 class="bg-primary text-white p-3">Adam's To Do List</h3>
<div class="my-1">
<input class="form-control" />
<button class="btn btn-primary mt-1">Add</button>
</div>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Description</th>
<th>Done</th>
</tr>
</thead>
<tbody>
<tr><td>Buy Flowers</td><td>No</td></tr>
<tr><td>Get Shoes</td><td>No</td></tr>
<tr><td>Collect Tickets</td><td>Yes</td></tr>
<tr><td>Call Joe</td><td>No</td></tr>
</tbody>
</table>
</body>
</html>Angular 开发工具包含了一个功能,当项目发生变化时,会自动更新浏览器。保存index.html 文件后,服务器将
检测更改并更新应用程序,反映新的内容,如图2-2 所示。


图2-2 编辑HTML 文件的内容
■ 提示:
更改一系列文件时,有时候浏览器可能无法加载和执行示例应用程序,特别是在运行后续章节中更复杂示例的
情况下。大多数情况下,HTTP 开发服务器都能触发浏览器的重新加载,一切都会很正常,但是如果真的遇到问题,
可能需要手动执行浏览器的重新加载。
index.html 文件中的HTML 元素展示了本章中创建的简单Angular 应用程序的外观。关键要素是显示用户名的
横幅、input 元素、用来添加新的待办事项的Add 按钮,以及包含所有待办事项并指示是否已完成的表格。
本书使用优秀的Bootstrap CSS 框架来为HTML 内容提供样式。Bootstrap 通过为元素指派CSS 类来应用样式,如下所示:
...
<h3 class="bg-primary text-white p-3">Adam's To Do List</h3>
...
这个h3 元素被指派三个CSS 类。bg-primary 类将元素的背景色设置为当前Bootstrap 主题的主要颜色。还有其
他主题颜色可用,包括bg-secondary、bg-info 和bg-danger。p-3 类为元素的所有边添加了一定量的填充,确保文本
的周围有一些空白。text-white 类将文本颜色设置为白色,这将增加与背景色的对比度。本书应用Bootstrap 时,HTML
元素将添加到这些类和其他类中。第4 章将概述最常用的类。
在下一节中,将这段HTML 内容从文件中移除,将其剪切成几个较小的部分,并使用它创建一个简单的Angular
应用程序。
2.3 向项目中添加Angular 功能
index.html 文件中的静态HTML 内容充当基本应用程序的占位符。用户应该可以查看待办事项列表、清点已完
成的项目并创建新项目。在接下来的几节中,将为项目添加一些基本的Angular 功能,让待办事项应用程序变得鲜
活起来。为了让应用程序尽可能简单,这里假设只有一位用户,而且不必保存应用程序的数据状态,这意味着如果
浏览器窗口被关闭或重新加载,那么对待办事项列表的更改将会丢失。在稍后的例子中——包括第7~10 章开发的
SportsStore 应用程序——将展示持久的数据存储。
2.3.1 准备HTML 文件
向应用程序中添加Angular 的第一步是准备index.html 文件,如代码清单2-3 所示。


代码清单2-3 准备在scr 文件夹的index.html 文件中添加Angular
<!DOCTYPE html>
<html>
<head>
<title>ToDo</title>
<meta charset="utf-8" />
</head>
<body class="m-1">
<todo-app>Angular placeholder</todo-app>
</body>
</html>而待办事项的内容则包含在表格的td 元素中,如下所示:
...
<tr><td>Buy Flowers</td><td>No</td></tr>
...
接下来的任务是将所有数据集中起来,创建一个数据模型。将数据与数据的呈现方式进行分离,这是MVC 模
式的关键思想之一,如第3 章所述。
■ 提示:
这里对模型进行了简化。模型还可以包含创建、加载、存储和修改数据对象所需的逻辑。在Angular 应用程序
中,此逻辑通常位于服务器端,并通过Web 服务访问。有关详细信息请参见第24 章。
Angular 应用程序通常用TypeScript 语言编写。第6 章介绍TypeScript,并解释它的工作原理及用途。TypeScript
是JavaScript 的一个超集,但其主要优点之一是可以让开发者使用最新的JavaScript 语言规范编写代码,其中一些新
增功能并非在所有运行Angular 应用程序的浏览器中都支持。在上一节中,angular-cli 添加到项目中的众多包中有一
个名为TypeScript 编译器的包,这个软件包有一个设置项,可在检测到TypeScript 文件变更时自动生成浏览器友好
的JavaScript 文件。
为了向应用程序中添加数据模型,将一个名为model.ts 的文件添加到todo/src/app 文件夹(TypeScript 文件的扩展
名为.ts),并添加如代码清单2-4 所示的代码。
代码清单2-4 todo/src/app 文件夹中model.ts 文件的内容
var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }]
};
TypeScript 最重要的功能之一是可以直接编写“普通的”JavaScript 代码,就像直接面向浏览器编程一样。在代
码清单2-4 中,使用JavaScript 对象字面量语法为一个名为model 的全局变量赋值。数据模型对象有一个user 属性(它
提供了应用程序用户的名称)和一个items 属性(该属性设置为一个对象数组,里面的每个对象都有action 和done 属
性,表示待办事项列表中的一个任务)。
这是使用TypeScript 时最重要的一个方面:不必使用TypeScript 提供的特性,而只使用所有浏览器都支持的
JavaScript 功能来编写整个Angular 应用程序,如代码清单2-5 中的代码那样。
但是TypeScript 的部分价值在于,它能够把使用JavaScript 语言中最新功能的代码转换成可以在任何地方运行的
代码,即使在不支持这些功能的浏览器中也是如此。代码清单2-5 显示了使用ECMAScript 6 标准(称为ES6)中添加的
JavaScript 功能改写的数据模型。
代码清单2-5 在src/app 文件夹的model.ts 文件中使用ES6 功能
export class Model {
user;
items;
constructor() {
this.user = "Adam";
this.items = [new TodoItem("Buy Flowers", false),
new TodoItem("Get Shoes", false),
new TodoItem("Collect Tickets", false),
new TodoItem("Call Joe", false)]
}
}
export class TodoItem {
action;
done;
constructor(action, done) {
this.action = action;this.done = done;
}
}
这依然是标准的JavaScript 代码,但class 关键字是在语言的更高版本中引入的,大多数Web 应用程序开发人员
并不熟悉,这是因为旧版浏览器不支持它。class 关键字用于定义类型,可以使用new 关键字实例化这些类型,以创
建具有明确定义的数据和行为的对象。
在JavaScript 语言的最新版本中添加的许多功能都是语法糖,帮助程序员避免一些最常见的JavaScript 陷阱,例
如不常见的类型系统。class 关键字不会改变JavaScript 处理类型的方式,它只是让具有其他语言(如C#或Java)使用
经验的程序员更熟悉和更容易使用它。我喜欢JavaScript 的类型系统,它是动态的,表达能力也不错,但使用类更
可预测,更不容易出错,并且简化了Angular 的使用,这是因为Angular 是针对最新的JavaScript 功能而设计的。
■ 提示:
如果不熟悉在JavaScript 规范的最新版本中添加的功能,也不要担心。第5 章和第6 章提供了一些入门知识,
介绍如何使用一些能够让Angular 更易用的JavaScript 功能来编写代码,第6 章还介绍了一些有用的TypeScript 特有
功能。
export 关键字与JavaScript 模块有关。在使用模块时,每个TypeScript 或JavaScript 文件被认为是一个独立的功
能单元,使用export 关键字来标识要在应用程序其他位置使用的数据或类型。JavaScript 模块用于管理项目中不同文
件之间产生的依赖关系,并避免在HTML 文件中手动管理一组复杂的script 元素。有关模块如何工作的详细信息,
请参见第7 章。
2.3.3 创建模板
应用程序需要一种途径向用户显示模型中的数据值。在Angular 中,这项工作由模板完成,这里的模板是指包
含由Angular 执行的指令的HTML 片段。该项目的angular-cli 设置程序在src/app 文件夹中创建一个名为
app.component.html 的模板文件。这个文件经过编辑,添加了如代码清单2-6 所示的标记来替换占位符内容。该文件
的名称遵循标准Angular 命名约定,稍后将具体解释。
代码清单2-6 src/app 文件夹中app.component.html 文件的内容
<h3 class="bg-primary p-1 text-white">{ { getName() }}'s To Do List</h3>
稍后会向这个文件中添加更多元素,但刚开始时一个h3 元素足矣。使用双括号{ {和}}就可以在模板中包含数据
值,而Angular 会对双括号之间的内容求值,以获取要显示的值。
{ {和}}字符是数据绑定的示例,这意味着它们在模板和数据值之间建立关联。数据绑定是一项重要的Angular
功能,本章向示例应用程序添加功能时以及第Ⅱ部分详细描述这些功能时,会给出更多示例。在这里,数据绑定会
告诉Angular 调用一个名为getName 的函数,并使用返回结果作为h3 元素的内容。目前在应用程序的任何位置都找
不到getName 函数,下一节将创建它。
2.3.4 准备组件
Angular 组件负责管理模板并为其提供所需的数据和逻辑。这似乎表明组件的功能比较宽泛,这是因为组件作
为Angular 应用程序的组成部分,它们完成大部分的重要工作。总之,它们可用于完成各种任务。
目前,项目中有一个数据模型,其中包含一个需要显示名称的user 属性,还有一个模板可以通过调用getName
属性来显示该名称。项目还需要一个组件,充当它们之间的桥梁。angular-cli 设置程序在todo/src/app 文件夹中创建
了一个名为app.component.ts 的占位符组件文件,该文件经过编辑,将原始内容替换成代码清单2-7 所示的代码。
代码清单2-7 src/app 文件夹中app.component.ts 文件的内容
import { Component } from "@angular/core";
import { Model } from "./model";
@Component({selector: "todo-app",
templateUrl: "app.component.html"
})
export class AppComponent {
model = new Model();
getName() {
return this.model.user;
}
}
这仍然是JavaScript 代码,但它依赖从前可能没有的一些陌生功能,这些功能是Angular 开发的基础。该代码清
单中的代码可以分为三个主要部分,如以下几节所述。
1. 理解导入语句
import 关键字与export 关键字相对应,用于声明对JavaScript 模块内容的依赖。代码清单2-7 中两次用到import
关键字,如下所示:
...
import { Component } from "@angular/core";
import { Model } from "./model";
...
该代码清单使用第1 条import 语句加载@angular/core 模块,其中包含关键的Angular 功能,包括对组件的支持。
在使用模块时,import 语句指定在大括号之间要导入的类型。在这里,import 语句用于从模块加载组件类型。
@angular/core 模块包含许多已经打包在一起的类,以便浏览器可以将它们全部加载到单个JavaScript 文件中。
第2 条import 语句用于从项目的文件中加载Model 类。此类导入语句的目标均以./开头,表示该模块是相对于
当前文件定义的。
请注意,所有import 语句都不包含文件扩展名。这是因为import 语句的目标与浏览器加载的文件之间的关系由
模块加载器管理,稍后会在2.3.5 节中配置模块加载器。
2. 理解装饰器
代码清单2-7 中最奇怪的部分是:
...
@Component({
selector: "todo-app",
templateUrl: "app.component.html"
})
...
这是一个装饰器(decorator),它提供关于类的元数据。这里是@Component 装饰器,顾名思义,它告诉Angular 这是
一个组件。装饰器通过其属性提供配置信息,对于@Component 装饰器,它包括名为selector 和templateUrl 的属性。
selector 属性指定一个CSS 选择器,用于匹配该组件所要应用的HTML 元素:这里指定了todo-app 元素(添加到
代码清单2-3 的index.html 文件中)。Angular 应用程序启动时,Angular 将扫描当前文档中的HTML,并查找与组件
对应的元素。Angular 会找到todo-app 元素,并知道应该将其置于该组件的控制之下。
templateUrl 属性用于指定组件的模板,对于该组件而言,该模板为app.component.html 文件。本书第Ⅱ部分描
述了可用于@Component 装饰器的其他属性以及Angular 支持的其他装饰器。
3. 理解类
代码清单2-7 的最后一部分定义了一个类,Angular 实例化该类以创建组件:
...
export class AppComponent {
model = new Model();
getName() {
return this.model.user;
}
}
...这些语句定义了一个名为AppComponent 的类,它拥有model 属性和getName 函数,它提供了支持代码清单2-6
所示模板中数据绑定所需的功能。
当创建AppComponent 类的新实例时,把model 属性设置为代码清单2-5 中定义的Model 类的新实例。getName
函数返回由Model 对象定义的user 属性的值。
2.3.5 将应用程序组合起来
至此,构建一个简单的Angular 应用程序所需的3 个关键功能——模型、模板和组件都已完成。把更改保存到
app.component.ts 文件中时,已经实现了足够多的功能,可以将3 个部分组合在一起,并显示如图2-4 所示的输出。


图2-4 示例应用程序中的简单Angular 功能
使用angular-cli 创建项目的一个好处是不必担心创建Angular 应用程序所需的基本文件,而缺点是跳过这些文件
意味着会错过一些值得探索的重要细节。
Angular 应用程序需要模块(module)。由于命名选择的缘故,Angular 开发中使用了两种类型的模块。JavaScript
模块是包含JavaScript 功能(通过import 关键字使用该功能,参见第6 章)的文件。另一种类型的模块是Angular 模块,
它用于描述应用程序或一组相关功能。每个应用程序都有一个根模块(root module),它为Angular 提供启动应用程序
所需的信息。
当angular-cli 设置项目时,它在todo/src/app 文件夹中创建了一个名为app.module.ts 的文件(这是根模块的常用文
件名),并添加了如代码清单2-8 所示的代码。
代码清单2-8 src/app 文件夹中app.module.ts 文件的默认内容
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Angular 模块的目的是通过@NgModule 装饰器定义的属性来提供配置信息。第21 章将详细解释模块的工作原
理,但目前只需要知道,装饰器的imports 属性告诉Angular,该应用程序将在浏览器中运行,需要导入所需的相关
功能,declarations 和bootstrap 属性告诉Angular 关于应用程序中的所有组件,以及应该使用哪个组件来启动应用程
序(在这个简单示例应用程序中只有一个组件,因此它是这两个属性的唯一值)。
要创建待办事项应用程序,需要使用Angular的特性来处理表单元素,这些元素是在名为@angular/forms的
Angular模块中定义的。为启用这些功能,需要修改app.module.ts文件,如代码清单2-9所示。
代码清单2-9 在src/app 文件的app.module.ts 文件中启用表单支持
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from "@angular/forms";
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Angular 应用程序还需要一个引导文件,其中包含启动应用程序所需的代码。引导文件名为main.ts,它在todo/src
文件夹中创建,其代码如代码清单2-10 所示。本章的main.ts 文件不需要修改。
代码清单2-10 src 文件夹中main.ts 文件的内容
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.log(err));
虽然本书着重于在Web 浏览器中运行的应用程序,但Angular 旨在运行于各种环境中。引导文件中的代码选择
要使用的平台,并加载根模块,这是应用程序的入口。
■ 提示:
调用platformBrowserDynamic( ).bootstrapModule 方法适合基于浏览器的应用程序,浏览器平台是本书的重点。
如果正在使用不同的平台(例如Ionic 移动开发框架),就必须使用所用平台特有的不同引导方法。支持Angular 的每
个平台的开发人员都提供了平台特有的引导方法的详细信息。
浏览器执行引导文件中的代码,这会调用Angular,后者又处理HTML 文档并发现todo-app 元素。用于定义组
件的selector 属性匹配到todo-app 元素,这让Angular 删除占位符内容,并将其替换为组件模板(从app.component.html
文件自动加载)。模板经过解析,发现了{ {和}}数据绑定,并对其中包含的表达式求值,调用getName 方法并显示图
中所示的结果。虽然这个结果可能不会给人留下深刻印象,但这是一个良好开端,它为添加更多功能提供了基础。
■ 提示:
在任何Angular 项目中,都必须耗费一段时间来定义应用程序的主要部分,并将它们有机地组织起来。在这段
时间里,可能会感觉到自己在做很多工作,但是很少有回报。但可以肯定的是,这种初期投入最终会得到应有的回
报。当开始构建更加复杂的实际Angular 应用程序(如第7 章中的更大示例)时,可以看出:虽然需要大量的初始设置
和配置,但是随后就可以快速实现所需的功能。

节选自《Angular 高级编程(第3 版)》第一章

《Angular 高级编程(第3 版)》试读电子书,免费提供,有需要的留下邮箱,一有空即发送给大家。邮箱留到微信回复更快(邮箱地址+试读书名),别忘啦顶哦!

微信:qinghuashuyou  

更多最新图书请点击查看哦(即日起:关注@qinghuashuyou 发送:关注技术方向,不定时有新书上新,参与互动即有机会获得推广新书样书)

猜你喜欢

转载自blog.csdn.net/qinghuawenkang/article/details/98761314