Angular 教程 - 第 2 部分





5.00/5 (9投票s)
创建您的第一个 Angular 项目并理解组件和模块等各种概念
- 下载 Lab6 CustomerAngularProject - 94.1 KB
- 下载 学习 Angular 100 页电子书 - 3.6 MB
- 下载 学习 Angular 100 页电子书 - 3.6 MB
- 下载 学习 Angular 100 页电子书 - 3.5 MB
系列文章
- 学习 Angular 教程 - 了解 Node、TypeScript、模块加载器/打包器和 VS Code
- 学习 Angular 教程 - 第二部分 - 创建一个简单的基本 Angular 应用程序,其中包含一个屏幕,并了解组件和模块等重要概念
- 学习 Angular 教程 - 第三部分 - 实现 SPA 和验证
- 学习 Angular 教程 - 第四部分 - 如何发起 HTTP 请求以及如何使用 Input 和 Outputs 创建自定义 Angular 组件
- 学习 Angular 教程 - 第五部分 - 两个实验 - 如何将 JQuery 与 Angular 结合使用以及懒加载路由
- 学习 Angular 教程 - 第六部分 - 两个实验 - 使用提供程序进行 Pipes 和 DI
实验 6:组件和模块(运行您的第一个 Angular 应用程序)1
目录
- 引言
- 步骤 1:NPM 安装以获取 Angular 框架
- NPM 安装期间的常见错误
- 步骤 2:TypeScript 配置 tsconfig.json
- 步骤 3:配置 SystemJS 模块加载器
- 理解 Angular 组件和模块架构
- 步骤 4:逐步遵循 MVW - 创建文件夹
- 步骤 5:创建模型
- 步骤 6:创建组件
- 步骤 7:创建客户 HTML UI - 指令(Directives)和插值(Interpolation)
- 步骤 8:创建模块
- 步骤 9:创建“Startup.ts”文件
- 步骤 10:使用主 Angular 页面调用“Startup.ts”文件
- 步骤 11:设置 TypeScript 编译器
- 步骤 12:运行 http-server
- 如何运行源代码?
- 下一篇文章有什么内容?
- 历史
引言
在之前的实验中,我们研究了 Angular、Node、TypeScript、加载器和打包器的基础知识。在本实验中,我们将配置 Angular 环境,并尝试创建基本的客户屏幕并使其运行起来。所以让我们从第一个步骤开始,下载 Angular 框架并配置 TypeScript 编译器。
步骤 1:NPM 安装以获取 Angular 框架
因此,让我们创建一个名为“Angular”的文件夹,并使用 VS Code 打开它。请参考实验 3 了解如何使用 VS Code。如果您想在 Visual Studio 中使用 Angular,您可以观看此视频。如果您是 Eclipse 用户,请在下方给我留言。
正如我们在实验 1 中讨论的,“Node
”有“npm
”,它帮助我们获取 JavaScript 开源库。因此,请创建一个 package.json 文件,其中包含以下详细信息,并在 VS Code 的集成命令行中执行“npm install
”。
{
"name": "angular-quickstart",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@angular/common": "4.0.0",
"@angular/compiler": "4.0.0",
"@angular/core": "4.0.0",
"@angular/forms": "4.0.0",
"@angular/http": "4.0.0",
"@angular/platform-browser": "4.0.0",
"@angular/platform-browser-dynamic": "4.0.0",
"@angular/router": "4.0.0",
"@angular/upgrade": "4.0.0",
"angular-in-memory-web-api": "0.3.2",
"bootstrap": "^3.3.6",
"core-js": "^2.4.1",
"http-server": "^0.10.0",
"reflect-metadata": "^0.1.3",
"rxjs": "^5.4.1",
"systemjs": "0.19.27",
"zone.js": "^0.8.4"
},
"devDependencies": {
"@types/core-js": "^0.9.42",
"typescript": "2.3.4"
}
}
如果所有 npm install 都成功运行,您应该会在 VS Code 项目目录中看到一个 node_modules 文件夹,其中包含以下文件夹结构。 如果您进入“Angular”文件夹,您会看到很多文件夹,如 common、http、forms core 等。简单来说,Angular 是模块化的。 他们为表单、HTTP、核心等开发了独立的组件。 | ![]() |
在 AngularJS 1.X 中,我们只有一个JS 文件,其中包含整个框架。所以您只需将那个单一的 Angular 1.X JS 文件拖放到 HTML 页面上,您就可以准备好 Angular 1.X 环境了。但是,将整个框架放在一个 JS 文件中的问题是,您必须包含所有功能,无论您是否需要它们。
例如,即使您不使用 HTTP,该功能仍会被加载。在 Angular 的情况下,我们有单独的离散组件,这使得 Angular 非常出色。
NPM 安装期间的常见错误
这是 Angular 中最关键的部分。您可以看到在“package.json”文件中,我们有很多依赖项,这些依赖项互相依赖。所以如果一个版本不兼容,整个 NPM 命令就会失败。因此,以下几点需要注意。
首先,保持 NPM 更新到最新版本,否则您可能会收到侧边显示的警告。 即使您没有收到此警告,也要保持最新的 NPM 版本。 | ![]() |
要获取最新的 NPM 版本,您需要使用“npm install -g npm
”。此命令将更新 NPM 本身。
此外,您可能会遇到以下错误,显示模块之间的不兼容性。例如,在下图所示的情况下,它说“对于 Angular 4.0,您需要版本大于 0.8.4 的Zone.js”。
因此,转到您的 project.json,修复版本号,删除 node_modules 文件夹,然后再次执行 NPM。
版本不匹配的错误可能会非常严重,如图所示。有时修复“package.json”可能会非常痛苦和迭代。当您进行这些迭代时,请确保删除“node_modules”文件夹,这样您就不会引用旧版本。
您还可能遇到如下所示的“ERR nottarget”错误。此错误表示找不到特定的版本号。使用“npm view packagename version
”命令获取最新版本并相应更新您的包。
步骤 2:TypeScript 配置 tsconfig.json
同样在同一个文件夹中,我们需要创建 tsconfig.json,它定义了 TypeScript 如何编译。不用担心其中的设置。我们会随着教程的进行进行解释。请记住不要过度学习。现在,只需注意以下文件定义了 TSC 如何编译。
{
"compilerOptions": {
"target": "es5",//defines what sort of code ts generates,
//es5 because it's what most browsers
//currently UNDERSTAND.
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true, //for Angular to be able to use metadata,
//we specify in our components.
"experimentalDecorators": true,//angular needs decorators like
//@Component, @Injectable, etc.
"removeComments": false,
"noImplicitAny": false,
"noStrictGenericChecks": true,
"lib": ["es2016", "dom"]
}
}
步骤 3:配置 SystemJS 模块加载器
SystemJS 文件定义了 SystemJS 如何加载框架的配置。因此,我们将此文件放在同一个文件夹中,名为“systemjs.config.js”。名称必须完全是“systemjs.config.js”,因为 SystemJS 会查找此名称。
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': '../node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'startup',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser':
'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic':
'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'lodash':'node_modules/lodash',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api':
'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'moment': 'npm:moment',
// ag libraries
'ag-grid-ng2': '../node_modules/ag-grid-ng2',
'ag-grid': '../node_modules/ag-grid',
'jquery': '../node_modules/jquery/dist/jquery.js',
'ng2-auto-complete': '../node_modules/ng2-auto-complete/dist'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: '../Startup/Startup.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
'angular-in-memory-web-api': {
main: './index.js',
defaultExtension: 'js'
},
'lodash': { main: './index.js', defaultExtension: 'js' },
moment: {
defaultExtension: 'js'
},
'ag-grid-ng2': {
defaultExtension: "js"
},
'ag-grid': {
defaultExtension: "js"
},
'ng2-auto-complete': {
main: 'ng2-auto-complete.umd.js', defaultExtension: 'js'
}
}
});
})(this);
理解 Angular 组件和模块架构
正如我们在上一节中所说的,Angular 的整个目标是绑定模型和视图。在 Angular 中,绑定代码官方称为“Component
”。因此,今后我们将使用“Component
”一词来指代绑定代码。
在企业项目中,您可能会有很多组件。组件多了,管理项目会变得非常困难。因此,您可以将组件逻辑地分组到模块中。
![]() | 因此,今后我将使用两个术语
|
步骤 4:逐步遵循 MVW - 创建文件夹
在我们开始编码之前,让我们可视化编码的步骤。正如我们提到的,Angular 是一个绑定框架。它遵循 MVW 架构。它将 HTML UI 与 JavaScript 代码(模型)绑定。
所以,如果我们可视化它,它看起来会像下面的图片。所以让我们从右到左移动。让我们按以下顺序进行编码
- 创建模型。
- 创建组件。
- 创建模块。
- 创建 HTML UI。
所以,让我们先在我们的项目中创建四个文件夹
- View 文件夹:此文件夹将包含 HTML UI。
- Model 文件夹:此文件夹将包含主要的业务 TypeScript 类。
- Component 文件夹:此文件夹将包含将 HTML UI 和 Model 绑定的代码。
- Module:此文件夹将包含逻辑上分组组件的代码。
要创建 VS Code 中的文件夹,您可以使用“新建文件夹”图标,或者右键单击也可以创建文件夹。
步骤 5:创建模型
![]() | 模型只不过是一个具有属性和行为的类。因此,让我们先创建具有三个属性的客户模型,“ 因此,右键单击“Model”文件夹并添加一个新文件“Customer.ts”。将此文件的扩展名保留为“.ts”,因为它是一个 TypeScript 文件。 编译时,TypeScript 命令只能识别扩展名为“.ts”的文件。 |
在“Customer.ts”中,让我们创建一个具有三个属性的“Customer
”类。在本书中,我们不会深入讲解 TypeScript 的基础知识,请您观看这个一小时的 TypeScript 训练视频,其中更详细地解释了 TypeScript。
export class Customer {
CustomerName: string = "";
CustomerCode: string = "";
CustomerAmount: number = 0;
}
步骤 6:创建组件
![]() | 接下来我们需要编写的代码是绑定代码。Angular 中的绑定代码由称为“ 因此,右键单击 component 文件夹,然后像左侧的图片所示一样添加“CustomerComponent.ts”文件。 |
在组件中,我们需要导入两样东西——Angular 核心和我们的 Customer
模型。请注意,“import
”是 TypeScript 语法而不是 JavaScript。因此,如果您不理解代码,请在继续之前观看这个1 小时学习 TypeScript 视频。
import {Customer} from '../Model/Customer'
import {Component} from "@angular/core"
第一行将“Customer
”类导入到“CustomerComponent.ts”中。此导入之所以成为可能,是因为我们在“Customer.ts”文件中编写了“export
”。import
和 export
生成遵循 CommonJs、AMD 或 UMD 规范的代码。如果您不熟悉这些规范,请观看这个CommonJs 视频,其中更详细地解释了该协议。
import {Customer} from '../Model/Customer'
![]() | 让我们尝试理解“ “../”表示向上移动一个文件夹。所以我们目前在“Component”文件夹中,所以使用“../”,它会导航到根目录,然后从该点进入“Model”文件夹。 |
下一个 import 命令导入 Angular 核心组件。在这里,我们没有使用“../”等给出任何相对路径。那么 TypeScript 是如何定位 Angular 核心组件的呢?
import {Component} from "@angular/core"
如果您还记得,我们曾经使用 node 加载 Angular,而 node 会加载“node_modules”文件夹中的 JS 文件。那么 TypeScript 编译器是如何自动知道它必须从“node_modules”文件夹加载 Angular 组件的呢?
TypeScript 编译器使用“tsconfig.json”文件中的配置。在配置中,我们有一个名为“moduleResolution
”的属性。它有两个值
- Classic:在此模式下,TypeScript 依赖于“./”和“../”来定位文件夹。
- Node:在此模式下,TypeScript 首先尝试在“node_modules”文件夹中定位组件,如果找不到,则遵循“../”约定遍历文件夹。
在我们的 tsconfig.json 中,我们将模式定义为“node
”。这使得 TypeScript 自动在“node_modules”文件夹中查找模块。这使得 Angular 组件的“import
”能够工作。
{
{
....
....
"moduleResolution": "node",
....
....
}
}
因此,现在这两个 import
语句都已应用,让我们创建“CustomerComponent
”,并从中将“Customer
”对象公开到 UI,对象名称为“CurrentCustomer
”。
export class CustomerComponent {
CurrentCustomer:Customer = new Customer();
}
正如我们之前所说,组件连接/绑定模型到 HTML UI。因此,应该有一些代码表明“CustomerComponent
”与 HTML UI 绑定。这可以通过一种称为“Component MetaData Attribute”(组件元数据属性)的东西来完成。组件元数据属性以“@Component
”开头,它有一个“templateUrl
”属性,指定了与组件类关联的 HTML UI。
@Component({
selector: "customer-ui",
templateUrl: "../UI/Customer.html"
})
然后将此属性装饰在组件的顶部。以下是完整代码。
@Component({
selector: "customer-ui",
templateUrl: "../UI/Customer.html"
})
export class CustomerComponent {
CurrentCustomer:Customer = new Customer();
}
| 简单来说,绑定代码只是一个简单的 TypeScript 类,它被“ |
以下是 Angular 组件的完整代码。
// Import statements
import {Component} from "@angular/core"
import {Customer} from '../Model/Customer'
// Attribute metadata
@Component({
selector: "customer-ui",
templateUrl: "../UI/Customer.html"
})
// Customer component class exposing the customer model
export class CustomerComponent {
CurrentCustomer:Customer = new Customer();
}
步骤 7:创建客户 HTML UI - 指令(Directives)和插值(Interpolation)
现在,从“CustomerComponent
”中,通过“CurrentCustomer
”对象将“Customer
”公开到 UI。因此,在 HTML UI 中,我们在绑定时需要引用此对象。
在 HTML UI 中,对象通过使用“Directives
”(指令)进行绑定。Directives
是指导如何与 UI 绑定的标签。
例如,如果我们想将“CustomerName
”绑定到 HTML 文本框,代码如下所示
- “
[(ngModel)]
”是一个指令,它将帮助我们从对象发送数据到 UI,反之亦然。 - 看看绑定到对象的方式。它引用属性为“
CurrentCustomer.CustomerName
”,而不是仅仅“CustomerName
”。为什么??因为如果您还记得从“CustomerComponent
”公开的对象是“CurrentCustomer
”对象。所以您需要限定“CurrentCustomer.CustomerCode
”。
<input type="text" [(ngModel)]="CurrentCustomer.CustomerName">
|
|
有时我们可能想在浏览器中显示对象数据。通过使用“{{
”大括号,我们可以将对象数据与 HTML 标签一起显示。在下面的 HTML 中,我们将“CustomerName
”与 HTML BR
标签混合显示。这些大括号被称为“INTERPOLATION”(插值)。如果您看到插值的字典含义,它意味着将不同性质的东西插入到其他东西中。
在下面的代码中,我们将对象数据插入到 HTML 中。
{{CurrentCustomer.CustomerName}}<br />
以下是带有绑定指令和插值的完整 HTML UI 代码。
<div>
Name:
<input type="text" [(ngModel)]="CurrentCustomer.CustomerName"><br /><br />
Code:
<input type="text" [(ngModel)]="CurrentCustomer.CustomerCode"><br /><br />
Amount:
<input type="text" [(ngModel)]="CurrentCustomer.CustomerAmount"><br /><br />
</div>
{{CurrentCustomer.CustomerName}}<br /><br />
{{CurrentCustomer.CustomerCode}}<br /><br />
{{CurrentCustomer.CustomerAmount}}<br /><br />
步骤 8:创建模块
模块是一个容器,或者您可以说它是组件和其他服务的逻辑分组。
因此,此模块中的第一个 import 是“CustomerComponent
”组件。
import { CustomerComponent } from '../Component/CustomerComponent';
我们还需要从核心 Angular 导入“BrowserModule
”和“FormsModule
”。“BrowserModule
”包含我们可以编写 IF
条件和 FOR
循环的组件。“FormsModule
”提供了诸如“ngModel
”之类的指令功能、表达式等。
import { BrowserModule } from '@angular/platform-browser';
import {FormsModule} from "@angular/forms"
我们还需要创建一个 TypeScript 类“MainModuleLibrary
”。此时,这个类中没有任何代码,但它可以包含提供组件级别逻辑的代码,例如缓存、该组件组的初始化代码等。
export class MainModuleLibrary { }
要创建一个模块,我们需要从 Angular 核心导入“NgModule
”。这有助于我们定义模块指令。
import { NgModule } from '@angular/core';
“NgModule
”有三个属性
Imports
:如果此模块正在利用其他模块,我们在该部分定义模块。Declarations
:在此部分,我们定义模块的组件。目前,我们只有一个组件‘CustomerComponent
’。Bootstrap
:此部分定义将运行的第一个组件。例如,我们可以有“HomeComponent
”、“CustomerComponent
”等。但是第一个运行的组件是“HomeComponent
”,因此我们需要在此部分定义。
@NgModule({
imports: [BrowserModule,
FormsModule],
declarations: [CustomerComponent],
bootstrap: [CustomerComponent]
})
以下是本节讨论的 Angular 模块的完整代码。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {FormsModule} from "@angular/forms"
import { CustomerComponent } from '../Component/CustomerComponent';
@NgModule({
imports: [BrowserModule,
FormsModule],
declarations: [CustomerComponent],
bootstrap: [CustomerComponent]
})
export class MainModuleLibrary { }
步骤 9:创建“Startup.ts”文件
![]() | 因此,我们已经创建了 UI,我们已经创建了模型,我们已经创建了组件,并且这些组件被分组到模块中。在 Angular 应用程序中,您可以拥有许多模块。 因此,您需要定义启动模块。所以,让我们创建一个“Startup.ts”文件,它将定义启动模块。 |
以下是“Startup.ts”文件,我们在其中定义了哪个模块将被引导。
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { MainModuleLibrary } from '../Module/MainModuleLibrary';
const platform = platformBrowserDynamic();
platform.bootstrapModule(MainModuleLibrary);
步骤 10:使用主 Angular 页面调用“Startup.ts”文件
所以,让我们创建一个启动 HTML 页面来调用“Startup.ts”。现在在这个页面中,我们需要像下面的代码所示一样导入四个 JavaScript 框架文件 Shim、Zone、Meta-data 和 System JS。
<script src="../../node_modules/core-js/client/shim.min.js"></script>
<script src="../../node_modules/zone.js/dist/zone.js"></script>
<script src="../../node_modules/reflect-metadata/Reflect.js"></script>
<script src="../../node_modules/systemjs/dist/system.src.js"></script>
以下是 JS 文件的用途
Shim.min.js | 此框架可确保 ES 6 JavaScript 可以在旧浏览器中运行。 |
Zone.js | 此框架确保我们可以将一组异步活动视为一个区域。 |
Reflect.js | 帮助我们在 JavaScript 类上应用元数据。我们目前将 @NgModule 和 @NgComponent 用作属性。 |
System.js | 此模块将帮助使用 CommonJS、AMD 或 UMD 等模块协议加载 JS 文件。 |
在此 HTML 页面中,我们调用了“systemjs.config.js”文件。该文件将告诉 System JS 在浏览器中加载哪些文件。
<script src="../systemjs.config.js"></script>
<script>
System.config({
"defaultJSExtensions": true
});
System.import('startup').catch(function (err) { console.error(err); });
</script>
在“import
”中,我们需要指定“startup
”,这将调用“startup.js”文件。
System.import('startup').catch(function (err) { console.error(err); });
我们的客户屏幕名为“Customer.html”。所以要加载到这个屏幕,我们需要定义一个占位符。因此,在这个占位符中,我们的 Customer
HTML 页面将加载。
<customer-ui></customer-ui>
如果您还记得,当我们创建 component
类时,我们说过要加载 HTML 页面到一个选择器中。所以那个选择器就是用来加载我们的 Customer
页面的标签(占位符)。
@Component({
selector: "customer-ui",
templateUrl: "../UI/Customer.html"
})
以下是包含所有脚本和占位符标签的完整 HTML 页面。
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="../../node_modules/core-js/client/shim.min.js"></script>
<script src="../../node_modules/zone.js/dist/zone.js"></script>
<script src="../../node_modules/reflect-metadata/Reflect.js"></script>
<script src="../../node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="../systemjs.config.js"></script>
<script>
System.config({
"defaultJSExtensions": true
});
System.import('startup').catch(function (err) { console.error(err); });
</script>
<body>
<customer-ui></customer-ui>
</body>
</html>
步骤 11:设置 TypeScript 编译器
我们还需要运行 TypeScript,以便 TS 文件能够编译成 JS 文件。因此,打开集成终端并输入“tsc -w
”。这将使 TypeScript 在后台持续运行。因此,当您键入时,TypeScript 会在文件更改时不断编译。
步骤 12:运行 http-server
因此,如果步骤 11 中一切正常,我们现在需要运行 http 服务器。要运行服务器,我们需要在 VS Code 集成终端中输入“http-server
”,如图所示。
![]() | 如果您的 80 端口被阻塞,您可以使用“ |
![]() | 因此,一旦 Web 服务器运行起来,您就可以浏览到主 Angular HTML 页面了。 请注意,Customer.html 不是主页面。该页面将在主 Angular 页面的占位符中加载。 一旦站点运行起来,在其中一个文本框中输入内容,然后查看表达式中绑定的自动输出。 |
★在两个终端中运行。您可以通过点击终端窗口中的“+”来打开两个终端。因此,在一个窗口中,您可以运行 http-server,在另一个窗口中,您可以运行 TypeScript 的监视模式。
如何运行源代码?
本书中附带的源代码不包含“node_modules”文件夹。因此,要运行代码,您需要使用 VS Code 打开文件夹,然后在您拥有“package.json”文件的文件夹中通过集成终端执行 NPM。
下一篇文章有什么内容?
在下一篇文章,即实验 3 中,我们将研究 Angular SPA 和验证,点击这里阅读下一篇文章。
如需进一步阅读,请观看下面的面试准备视频和分步视频系列
- Angular 教程面向初学者 | 分步学习 Angular
- Angular 面试问答
- ASP.NET MVC 面试题及答案
- C# 面试问答
- 分步学习 Azure
- SQL Server 分步教程
- RxJS 面试问答
- 1 小时学习 Angular(Angular 9)
- 8 小时分步学习 Angular
历史
- 2017年9月21日:初始版本