Angular 8 - 快速指南


Angular 8 - 简介

Angular 8 是一个基于 TypeScript 的全栈 Web 框架,用于构建 Web 和移动应用程序。主要优势之一是 Angular 8 支持 Web 应用程序,可以适应任何屏幕分辨率。Angular 应用程序完全兼容手机、平板电脑、笔记本电脑或台式机。Angular 8 为 Web 开发人员提供了一个优秀的用户界面库,其中包含可重用的 UI 组件。

此功能帮助我们创建单页应用程序(SPA)。SPA 是反应式且快速的应用程序。例如,如果单页中有一个按钮并单击该按钮,则该操作会在当前页面中动态执行,而无需从服务器加载新页面。Angular 8 是基于 Typescript 的面向对象编程,也支持服务器端编程功能。

角度版本比较

众所周知,Google 发布Angular版本是为了提高移动和 Web 开发能力。所有发布的版本都向后兼容,并且可以轻松更新到新版本。我们来看看已发布版本的比较。

AngularJS

AngularJs 是非常强大的 JavaScript 框架。它于 2010 年 10 月发布。AngularJS 基于模型视图控制器(MVC)架构,自动处理适合每个浏览器的 JavaScript 代码。

角2.0

Angular 2.0于2016年9月发布。它是AngularJS重新设计和重写的版本。AngularJs 重点关注控制器,但版本 2 已将重点改为组件。组件是应用程序的主要构建块。它支持加速渲染、更新页面以及为 Google Android 和 iOS 构建跨平台本机移动应用程序的功能。

角4.0

Angular 4.0 于 2017 年 3 月发布。它更新为 TypeScript 2.2,支持 ng if-else 条件,而 Angular 2 仅支持 if 条件。Angular 4.0 引入了动画包、Http 搜索参数,最终 Angular 4 应用程序变得更小、更快。

角5.0

Angular 5.0 于 2017 年 11 月发布。它支持一些显着功能,例如 HTTPClient API、Lambda 支持、改进的编译器和构建优化器。

角6.0

Angular 6.0 于 2018 年 5 月发布。此版本添加的功能包括更新的 Angular CLI、更新的 CDK、更新的 Angular Material、多个验证器以及反应式 JS 库的使用。

角7.0

Angular 7.0 于 2018 年 10 月发布。一些显着的功能是 Google 支持的社区、基于 POJO 的开发、模块化结构、声明式用户界面和模块化结构。

Angular 8 新功能

Angular 8 具有以下吸引人的新功能 -

  • Bazel 支持- 如果您的应用程序使用多个模块和库,Bazel 并发构建有助于在应用程序中更快地加载。

  • 延迟加载- Angular 8 将AppRoutingModule拆分为更小的包,并将数据加载到 DOM 中。

  • 差异加载- 当您创建应用程序时,Angular CLI 会生成模块,并且该模块将自动加载,然后浏览器将呈现数据。

  • Web Worker - 它在后台运行,不影响页面的性能。

  • CLI 工作流程的改进- Angular 8 CLI 命令 ng-build、ng-test 和 ng-run 已扩展到第三方库。

  • 路由器向后兼容性- Angular 路由器向后兼容性功能有助于为更大的项目创建路径,以便用户可以在惰性编码的帮助下轻松添加其编码。

  • 选择加入使用共享- 用户可以选择共享 Angular CLI 使用数据。

应用领域

下面列出了一些使用 Angular 框架的流行网站 -

  • Weather.com - 这是领先的天气预报网站之一。

  • Youtube - 这是一个由Google托管的视频和共享网站。

  • Netflix - 它是一家技术和媒体服务提供商。

  • PayPal - 这是一个在线支付系统。

Angular 8 - 安装

本章介绍如何在计算机上安装Angular 8 。在进行安装之前,我们首先验证先决条件。

先决条件

我们已经知道,Angular 是用TypeScript编写的。我们需要Nodenpm将文件编译成JavaScript之后,我们就可以部署我们的应用程序。为此,必须在系统中安装Node.js。希望您已经在计算机上安装了Node.js。

我们可以使用以下命令检查它 -

node --version

可以看到node的版本。如下所示 -

v14.2.0

如果未安装Node,您可以通过访问以下链接下载并安装 -

https://nodejs.org/en/download/。

角度8安装

Angular 8 CLI 安装基于非常简单的步骤。安装过程不会超过五分钟。

npm用于安装Angular 8 CLI。安装Node.js后, npm也会安装。如果您想验证它,请输入以下命令

npm -v

您可以看到下面的版本 -

6.14.4

让我们使用npm安装Angular 8 CLI,如下所示 -

npm install -g @angular/cli@^8.0.0

要验证Angular 8是否已正确安装在您的计算机上,请输入以下命令 -

ng version

您可以看到以下响应 -

Angular CLI: 8.3.26 
Node: 14.2.0 
OS: win32 x64 
Angular: ... 
Package                    Version 
------------------------------------------------------
@angular-devkit/architect  0.803.26 
@angular-devkit/core       8.3.26 
@angular-devkit/schematics 8.3.26 
@schematics/angular        8.3.26 
@schematics/update         0.803.26 
rxjs                       6.4.0

Angular 8 - 创建第一个应用程序

让我们创建一个简单的 Angular 应用程序并分析基本 Angular 应用程序的结构。

让我们使用以下命令检查系统中是否安装了 Angular 框架以及安装的 Angular 版本的版本 -

ng --version

这里,

ng是用于创建、管理和运行 Angular 应用程序的 CLI 应用程序。它用 JavaScript 编写,运行在 NodeJS 环境中。

结果将显示 Angular 版本的详细信息,如下所示 -

Angular CLI: 8.3.26 
Node: 14.2.0 
OS: win32 x64 
Angular: ... 
Package                    Version 
------------------------------------------------------
@angular-devkit/architect  0.803.26 
@angular-devkit/core       8.3.26 
@angular-devkit/schematics 8.3.26 
@schematics/angular        8.3.26 
@schematics/update         0.803.26 
rxjs                       6.4.0

因此,Angular 已安装在我们的系统中,版本为8.3.26

让我们创建一个 Angular 应用程序来检查我们的日常开支。让我们选择ExpenseManager作为新应用程序的选择。使用以下命令创建新应用程序。

cd /path/to/workspace 
ng new expense-manager

这里,

new是ng CLI 应用程序的命令之一。它将用于创建新的应用程序。它将询问一些基本问题以创建新的应用程序。让应用程序选择默认选项就足够了。对于下面提到的路由问题,请指定No我们将在稍后的“路由”章节中看到如何创建路由。

Would you like to add Angular routing? No

回答了基本问题后,ng CLI应用程序将在费用管理器文件夹下创建一个新的 Angular 应用程序。

让我们进入新创建的应用程序文件夹。

cd expense-manager

让我们检查一下应用程序的部分结构。应用程序的结构如下 -

| favicon.ico 
| index.html 
| main.ts 
| polyfills.ts 
| styles.css 
| 
+---app 
|  app.component.css 
|  app.component.html 
|  app.component.spec.ts 
|  app.component.ts 
|  app.module.ts 
| 
+---assets 
|  .gitkeep 
| 
+---environments 
   environment.prod.ts 
   environment.ts

这里,

  • 我们仅展示了应用程序最重要的文件和文件夹。

  • favicon.icoasset是应用程序的图标和应用程序的根资源文件夹。

  • polyfills.ts包含对浏览器兼容性有用的标准代码。

  • 环境文件夹将包含应用程序的设置。它包括生产和开发设置。

  • main.ts文件包含启动代码。

  • index.html是应用程序基础 HTML 代码。

  • styles.css是基本 CSS 代码。

  • app 文件夹包含 Angular 应用程序代码,将在接下来的章节中详细学习。

让我们使用以下命令启动应用程序 -

ng serve
10% building 3/3 modules 0 activei wds: Project is running at http://localhost:4200/webpack-dev-server/
i wds: webpack output is served from /

i wds: 404s will fallback to //index.html 
chunk {main} main.js, main.js.map (main) 49.2 kB [initial] [rendered] 
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 269 kB [initial] [rendered] 
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered] 
chunk {styles} styles.js, styles.js.map (styles) 9.75 kB [initial] [rendered] 
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.81 MB [initial] [rendered] 
Date: 2020-05-26T05:02:14.134Z - Hash: 0dec2ff62a4247d58fe2 - Time: 12330ms 
** Angular Live Development Server is listening on localhost:4200, open your 
browser on http://localhost:4200/ ** 
i wdm: Compiled successfully.

这里,serve是用于使用本地开发 Web 服务器编译和运行 Angular 应用程序的子命令。ng 服务器将启动一个开发 Web 服务器并在端口 4200 下为应用程序提供服务。

让我们启动浏览器并打开 http://localhost:4200。浏览器将显示应用程序,如下所示 -

浏览器应用程序

让我们更改应用程序的标题以更好地反映我们的应用程序。打开src/app/app.component.ts并更改代码,如下所示 -

export class AppComponent { 
   title = 'Expense Manager'; 
}

我们的最终应用程序将在浏览器中呈现,如下所示 -

浏览器应用程序

我们将在接下来的章节中更改应用程序并学习如何编写 Angular 应用程序。

Angular 8 - 架构

让我们看看本章中 Angular 框架的架构。

Angular 框架基于四个核心概念,如下 -

  • 成分。
  • 具有数据绑定指令的模板。
  • 模块。
  • 服务和依赖注入。

成分

Angular框架架构的核心是Angular Component。Angular 组件是每个 Angular 应用程序的构建块。每个 Angular 应用程序都由一个或多个Angular Component组成。它基本上是一个简单的 JavaScript / Typescript 类以及 HTML 模板和关联名称。

HTML 模板可以从其相应的 JavaScript / Typescript 类访问数据。组件的 HTML 模板可能包含使用其选择器值(名称)的其他组件。Angular 组件可能具有与其关联的可选 CSS 样式,并且 HTML 模板也可以访问 CSS 样式。

成分

让我们分析ExpenseManager应用程序中的AppComponent组件。AppComponent代码如下 -

// src/app/app.component.ts 
import { Component } from '@angular/core'; @Component({ 
   selector: 'app-root', 
   templateUrl: './app.component.html', 
   styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
   title = 'Expense Manager'; 
}

@Component是一个装饰器,它用于将普通的 Typescript 类转换为Angular Component

app-root是组件的选择器/名称,它是使用组件装饰器的选择器元数据指定的。app-root可由应用程序根文档src/index.html使用,如下所示

<!doctype html> 
<html lang="en"> 
   <head> 
      <meta charset="utf-8"> 
      <title>ExpenseManager</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> 
      <app-root></app-root> 
   </body> 
</html>

app.component.html是与组件关联的 HTML 模板文档。组件模板是使用@Component装饰器的templateUrl元数据指定的。

app.component.css是与组件关联的 CSS 样式文档。组件样式是使用@Component装饰器的styleUrls元数据指定的。

AppComponent属性(标题)可以在 HTML 模板中使用,如下所述 -

{{ title }}

模板

模板基本上是 HTML 的超级集合。模板包含 HTML 的所有功能,并提供附加功能将组件数据绑定到 HTML 中并动态生成 HTML DOM 元素。

模板的核心概念可以分为两项,如下:

数据绑定

用于将组件中的数据绑定到模板。

{{ title }}

这里,title是AppComponent中的一个属性,它使用Interpolation绑定到模板。

指令

用于包含逻辑并支持创建复杂的 HTML DOM 元素。

<p *ngIf="canShow">
   This sectiom will be shown only when the *canShow* propery's value in the corresponding component is *true* </p> 
<p [showToolTip]='tips' />

这里,ngIfshowToolTip(只是一个例子)是指令。ngIf仅当canShow为 true时才创建段落 DOM 元素。类似地,showToolTipAttribute Directives,它将工具提示功能添加到段落元素。

当用户将鼠标悬停在段落上时,会显示工具提示。工具提示的内容来自其相应组件的tips属性。

模块

Angular 模块基本上是相关特性/功能的集合。Angular Module将多个组件和服务分组到一个上下文中。

例如,动画相关功能可以分组为单个模块,并且 Angular 已经为动画相关功能提供了一个模块,即BrowserAnimationModule模块。

一个 Angular 应用程序可以拥有任意数量的模块,但只能将一个模块设置为根模块,该模块将引导应用程序,然后在必要时调用其他模块。模块也可以配置为访问其他模块的功能。简而言之,任何模块的组件都可以访问任何其他模块的组件和服务。

下图描述了模块及其组件之间的交互。

模块

让我们检查费用管理器应用程序的根模块。

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 { }

这里,

  • NgModule装饰器用于将普通 Typescript/JavaScript 类转换为Angular 模块

  • 声明选项用于将组件包含到AppModule模块中。

  • bootstrap选项用于设置AppModule模块的根组件。

  • providers选项用于包含AppModule模块的服务。

  • imports选项用于将其他模块导入到AppModule模块中。

下图描述了模块、组件和服务之间的关系

服务

服务是简单的 Typescript / JavaScript 类,提供非常具体的功能。服务将完成单一任务并做到最好。该服务的主要目的是可重用性。不是在组件内编写功能,而是将其分离到服务中,使其也可以在其他组件中使用。

此外,服务使开发人员能够组织应用程序的业务逻辑。基本上,组件使用服务来完成自己的工作。依赖注入用于正确初始化组件中的服务,以便组件无需任何设置即可在需要时访问服务。

Angular 应用程序的工作流程

我们已经学习了 Angular 应用程序的核心概念。让我们看看典型 Angular 应用程序的完整流程。

角度应用

src/main.ts是 Angular 应用程序的入口点。

src/main.ts 引导 AppModule (src/app.module.ts),它是每个 Angular 应用程序的根模块。

platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err));

AppModule引导AppComponent (src/app.component.ts),它是每个 Angular 应用程序的根组件。

@NgModule({ 
   declarations: [ 
      AppComponent 
   ], 
      imports: [ 
   BrowserModule 
   ], 
   providers: [], 
   bootstrap: [AppComponent] 
}) 
export class AppModule { }

这里,

AppModule通过导入选项加载模块。

AppModule还使用依赖注入(DI)框架加载所有注册的服务。

AppComponent呈现其模板(src/app.component.html)并使用相应的样式(src/app.component.css)。AppComponent名称,app-root用于将其放置在src/index.html中。

<!doctype html> 
<html lang="en"> 
   <head> 
      <meta charset="utf-8"> 
      <title>ExpenseManager</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> 
      <app-root></app-root> 
   </body> 
</html>

AppComponent可以使用应用程序中注册的任何其他组件。

@NgModule({ 
   declarations: [ 
      AppComponent 
      AnyOtherComponent
   ], 
   imports: [ 
      BrowserModule 
   ], 
   providers: [], 
   bootstrap: [AppComponent] 
}) 
export class AppModule { }

组件通过其模板中的指令使用目标组件的选择器名称来使用其他组件。

<component-selector-name></component-selector-name>

此外,所有 Angular 组件都可以通过依赖注入 (DI)框架访问所有注册的服务。

Angular 8 - Angular 组件和模板

正如我们之前了解到的,组件是 Angular 应用程序的构建块。Angular Component 的主要工作是生成一段名为view的网页。每个组件都有一个关联的模板,它将用于生成视图。

本章让我们学习一下组件和模板的基本概念。

添加组件

让我们在ExpenseManager应用程序中创建一个新组件。

打开命令提示符并转到ExpenseManager应用程序。

cd /go/to/expense-manager

使用ng生成组件命令创建一个新组件,如下所示 -

ng generate component expense-entry

输出

输出如下 -

CREATE src/app/expense-entry/expense-entry.component.html (28 bytes) 
CREATE src/app/expense-entry/expense-entry.component.spec.ts (671 bytes) 
CREATE src/app/expense-entry/expense-entry.component.ts (296 bytes) 
CREATE src/app/expense-entry/expense-entry.component.css (0 bytes) 
UPDATE src/app/app.module.ts (431 bytes)

这里,

  • ExpenseEntryComponent在 src/app/expense-entry 文件夹下创建。
  • 创建组件类、模板和样式表。
  • AppModule 已更新为新组件。

将 title 属性添加到ExpenseEntryComponent (src/app/expense-entry/expense-entry.component.ts) 组件。

import { Component, OnInit } from '@angular/core'; @Component({ 
   selector: 'app-expense-entry', 
   templateUrl: './expense-entry.component.html', styleUrls: ['./expense-entry.component.css'] 
}) 
export class ExpenseEntryComponent implements OnInit {
   title: string;
   constructor() { } 
   ngOnInit() { 
      this.title = "Expense Entry" 
   } 
}

使用以下内容更新模板src/app/expense-entry/expense-entry.component.html 。

<p>{{ title }}</p>

打开src/app/app.component.html并包含新创建的组件。

<h1>{{ title }}</h1>
<app-expense-entry></app-expense-entry>

这里,

app-expense-entry是选择器值,它可以用作常规 HTML 标签。

最后,应用程序的输出如下所示 -

HTML标签

我们将在进一步学习模板的过程中更新该组件的内容。

模板

Angular 组件的组成部分是Template。它用于生成 HTML 内容。模板是带有附加功能的纯 HTML。

附上模板

可以使用@component装饰器的元数据将模板附加到 Angular 组件。Angular 提供了两个元数据来将模板附加到组件。

模板网址

我们已经知道如何使用 templateUrl。它需要模板文件的相对路径。例如,AppComponent 将其模板设置为 app.component.html。

templateUrl: './app.component.html',

模板

模板可以将 HTML 字符串放置在组件本身内。如果模板内容很少,那么很容易将其作为组件类本身,以便于跟踪和维护。

@Component({ 
   selector: 'app-root', 
   templateUrl: `<h1>{{ title }}</h1>`, 
   styleUrls: ['./app.component.css'] 
}) 
export class AppComponent implements OnInit { 
   title = 'Expense Manager'; 
   constructor(private debugService : DebugService) {} ngOnInit() { 
      this.debugService.info("Angular Application starts"); 
   } 
}

附加样式表

Angular 模板可以使用类似于 HTML 的 CSS 样式。模板从两个来源获取其样式信息:a) 从其组件 b) 从应用程序配置。

组件配置

组件装饰器提供了两个选项,stylesstyleUrls来为其模板提供 CSS 样式信息。

  • Styles - styles选项用于将 CSS 放置在组件本身内。
styles: ['h1 { color: '#ff0000'; }']
  • styleUrls - styleUrls用于引用外部 CSS 样式表。我们也可以使用多个样式表。
styleUrls: ['./app.component.css', './custom_style.css']

应用配置

Angular 在项目配置(angular.json)中提供了一个选项来指定 CSS 样式表。angular.json中指定的样式将适用于所有模板。让我们检查一下angular.json,如下所示 -

{
"projects": { 
   "expense-manager": { 
      "architect": { 
         "build": { 
            "builder": "@angular-devkit/build-angular:browser", "options": { 
               "outputPath": "dist/expense-manager", 
               "index": "src/index.html", 
               "main": "src/main.ts", 
               "polyfills": "src/polyfills.ts", 
               "tsConfig": "tsconfig.app.json", 
               "aot": false, 
               "assets": [ 
                  "src/favicon.ico", 
                  "src/assets" 
               ], 
               "styles": [ 
                  "src/styles.css" 
               ], 
               "scripts": [] 
            }, 
         }, 
      } 
   }}, 
   "defaultProject": "expense-manager" 
}

这里,

styles选项将src/styles.css设置为全局 CSS 样式表。我们可以包含任意数量的 CSS 样式表,因为它支持多个值。

包括引导程序

让我们使用styles选项将 bootstrap 添加到ExpenseManager应用程序中,并更改默认模板以使用 bootstrap 组件。

打开命令提示符并转到 ExpenseManager 应用程序。

cd /go/to/expense-manager

使用以下命令安装bootstrapJQuery库

npm install --save bootstrap@4.5.0 jquery@3.5.1

这里,

我们安装了 JQuery,因为 bootstrap 广泛使用 jquery 来实现高级组件。

选项angular.json并设置 bootstrap 和 jquery 库路径。

{ 
   "projects": { 
      "expense-manager": { 
         "architect": { 
            "build": {
               "builder":"@angular-devkit/build-angular:browser", "options": { 
                  "outputPath": "dist/expense-manager", 
                  "index": "src/index.html", 
                  "main": "src/main.ts", 
                  "polyfills": "src/polyfills.ts", 
                  "tsConfig": "tsconfig.app.json", 
                  "aot": false, 
                  "assets": [ 
                     "src/favicon.ico", 
                     "src/assets" 
                  ], 
                  "styles": [ 
                     "./node_modules/bootstrap/dist/css/bootstrap.css", "src/styles.css" 
                  ], 
                  "scripts": [ 
                     "./node_modules/jquery/dist/jquery.js", "./node_modules/bootstrap/dist/js/bootstrap.js" 
                  ] 
               }, 
            }, 
         } 
   }}, 
   "defaultProject": "expense-manager" 
}

这里,

scripts选项用于包含 JavaScript 库。通过脚本注册的JavaScript将可供应用程序中的所有 Angular 组件使用。

打开app.component.html并更改如下指定的内容

<!-- Navigation --> 
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top"> 
   <div class="container"> 
      <a class="navbar-brand" href="#">{{ title }}</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> 
         <span class="navbar-toggler-icon">
         </span> 
      </button> 
      <div class="collapse navbar-collapse" id="navbarResponsive"> 
         <ul class="navbar-nav ml-auto"> 
            <li class="nav-item active"> 
            <a class="nav-link" href="#">Home
               <span class="sr-only">(current)
               </span>
            </a> 
            </li> 
            <li class="nav-item"> 
            <a class="nav-link" href="#">Report</a> 
            </li> 
            <li class="nav-item"> 
            <a class="nav-link" href="#">Add Expense</a> 
            </li> 
            <li class="nav-item"> 
            <a class="nav-link" href="#">About</a> 
            </li> 
         </ul> 
      </div> 
   </div> 
</nav> 
<app-expense-entry></app-expense-entry>

这里,

使用引导导航和容器。

打开src/app/expense-entry/expense-entry.component.html并将内容放在下面。

<!-- Page Content --> 
<div class="container"> 
   <div class="row"> 
      <div class="col-lg-12 text-center" style="padding-top: 20px;"> 
         <div class="container" style="padding-left: 0px; padding-right: 0px;"> 
            <div class="row"> 
            <div class="col-sm" style="text-align: left;"> {{ title }} 
            </div> 
            <div class="col-sm" style="text-align: right;"> 
               <button type="button" class="btn btn-primary">Edit</button> 
            </div> 
            </div> 
         </div> 
         <div class="container box" style="margin-top: 10px;"> 
         <div class="row"> 
         <div class="col-2" style="text-align: right;">  
            <strong><em>Item:</em></strong> 
         </div> 
         <div class="col" style="text-align: left;"> 
            Pizza 
         </div>
         </div> 
         <div class="row"> 
         <div class="col-2" style="text-align: right;">
            <strong><em>Amount:</em></strong> 
         </div> 
         <div class="col" style="text-align: left;"> 
            20 
         </div> 
         </div> 
         <div class="row"> 
         <div class="col-2" style="text-align: right;"> 
            <strong><em>Category:</em></strong> 
         </div> 
         <div class="col" style="text-align: left;"> 
            Food 
         </div> 
         </div> 
         <div class="row"> 
         <div class="col-2" style="text-align: right;"> 
            <strong><em>Location:</em></strong>
         </div> 
         <div class="col" style="text-align: left;"> 
            Zomato 
         </div> 
         </div> 
         <div class="row"> 
         <div class="col-2" style="text-align: right;"> 
            <strong><em>Spend On:</em></strong> 
         </div> 
         <div class="col" style="text-align: left;"> 
            June 20, 2020 
         </div> 
         </div> 
      </div> 
   </div> 
</div> 
</div>

重新启动应用程序。

应用程序的输出如下 -

重启标签

我们将在下一章中改进应用程序以处理动态费用条目。

Angular 8 - 数据绑定

数据绑定涉及如何将组件中的数据绑定到 HTML DOM 元素(模板)。我们可以轻松地与应用程序交互,而不必担心如何插入数据。我们可以通过两种不同的方式建立连接:一种是单向绑定,另一种是双向绑定。

在进入本主题之前,我们先在 Angular 8 中创建一个组件。

打开命令提示符并使用以下命令创建新的 Angular 应用程序 -

cd /go/to/workspace 
ng new databind-app 
cd databind-app

使用 Angular CLI创建一个测试组件,如下所述 -

ng generate component test

上面创建了一个新组件,输出如下 -

CREATE src/app/test/test.component.scss (0 bytes) CREATE src/app/test/test.component.html (19 bytes) CREATE src/app/test/test.component.spec.ts (614 bytes) 
CREATE src/app/test/test.component.ts (262 bytes) UPDATE src/app/app.module.ts (545 bytes)

使用以下命令运行应用程序 -

ng serve

单向数据绑定

单向数据绑定是组件与其模板之间的单向交互。如果您在组件中执行任何更改,它将反映 HTML 元素。它支持以下类型 -

字符串插值

一般来说,字符串插值是格式化或操作字符串的过程。在 Angular 中,插值用于将数据从组件显示到视图 (DOM)。它由表达式 {{ }} 表示,也称为小胡子语法。

让我们在组件中创建一个简单的字符串属性并将数据绑定到视图。

在test.component.ts文件中添加以下代码,如下所示 -

export class TestComponent implements OnInit { 
   appName = "My first app in Angular 8"; 
}

移至 test.component.html 文件并添加以下代码 -

<h1>{{appName}}</h1>

通过替换现有内容在app.component.html文件中添加测试组件,如下所示 -

<app-test></app-test>

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

您可以在屏幕上看到以下输出 -

字符串插值

事件绑定

事件是指鼠标单击、双击、悬停或任何键盘和鼠标操作等操作。如果用户与应用程序交互并执行某些操作,则会引发事件。它由括号()on-表示。我们有不同的方法将事件绑定到 DOM 元素。我们来简单的一一了解一下。

组件到视图的绑定

让我们了解简单的按钮单击甚至处理是如何工作的。

在test.component.ts文件中添加以下代码,如下所示 -

export class TestComponent { 
   showData($event: any){ 
      console.log("button is clicked!"); if($event) { 
         console.log($event.target); 
         console.log($event.target.value); 
      } 
   } 
}

$event\ast\:指的是firedevent\cdot\:在此场景中\:,\ast\:单击\ast\:是事件\cdot\ast$event 拥有有关事件和目标元素的所有信息。这里,目标是按钮。$event.target 属性将包含目标信息。

我们有两种方法来调用组件方法来查看(test.component.html)。第一个定义如下 -

<h2>Event Binding</h2> 
<button (click)="showData($event)">Click here</button>

或者,您可以在使用规范形式时使用前缀 - ,如下所示 -

<button on-click = "showData()">Click here</button>

在这里,我们没有使用$event,因为它是可选的。

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

典范

在这里,当用户单击按钮时,事件绑定理解按钮单击操作并调用组件 showData() 方法,因此我们可以断定它是单向绑定。

属性绑定

属性绑定用于将组件属性中的数据绑定到 DOM 元素。它由[]表示。

让我们通过一个简单的例子来理解。

在test.component.ts文件中添加以下代码。

export class TestComponent { 
   userName:string = "Peter"; 
}

在视图 test.component.html 中添加以下更改,

<input type="text" [value]="userName">

这里,

userName属性绑定到 DOM 元素<input>标记的属性。

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve
属性绑定

属性绑定

属性绑定用于将组件中的数据绑定到 HTML 属性。语法如下 -

<HTMLTag [attr.ATTR]="Component data">

例如,

<td [attr.colspan]="columnSpan"> ... </td>

让我们通过一个简单的例子来理解。

在test.component.ts文件中添加以下代码。

export class TestComponent { 
   userName:string = "Peter"; 
}

在视图 test.component.html 中添加以下更改

<input type="text" [value]="userName">

这里,

userName 属性绑定到 DOM 元素 <input> 标记的属性。

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve
属性绑定

类绑定

类绑定用于将组件中的数据绑定到 HTML 类属性。语法如下 -

<HTMLTag [class]="component variable holding class name">

类绑定提供了附加功能。如果组件数据是布尔值,则仅当它为 true 时该类才会绑定。多个类可以通过字符串(“foo bar”)以及字符串数组提供。还有更多选项可供选择。

例如,

<p [class]="myClasses">

让我们通过一个简单的例子来理解。

在 test.component.ts 文件中添加以下代码,

export class TestComponent { 
   myCSSClass = "red"; 
   applyCSSClass = false; 
}

在视图test.component.html中添加以下更改。

<p [class]="myCSSClass">This paragraph class comes from *myClass* property </p> 
<p [class.blue]="applyCSSClass">This paragraph class does not apply</p>

在test.component.css中添加以下内容。

.red { 
   color: red; 
} 
.blue { 
   color: blue; 
}

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

最终输出如下所示 -

类绑定

风格装订

样式绑定用于将组件中的数据绑定到 HTML 样式属性中。语法如下 -

<HTMLTag [style.STYLE]="component data">

例如,

<p [style.color]="myParaColor"> ... </p>

让我们通过一个简单的例子来理解。

在test.component.ts文件中添加以下代码。

myColor = 'brown';

在视图test.component.html中添加以下更改。

<p [style.color]="myColor">Text color is styled using style binding</p>

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

最终输出如下所示 -

风格装订

双向数据绑定

双向数据绑定是双向交互,数据以两种方式流动(从组件到视图以及视图到组件)。简单的例子是ngModel。如果您对属性(或模型)进行任何更改,它会反映在您的视图中,反之亦然。它是属性和事件绑定的组合。

NG模型

NgModel是一个独立的指令。ngModel指令将表单控件绑定到属性,并将属性绑定到表单控件。ngModel的语法如下 -

<HTML [(ngModel)]="model.name" />

例如,

<input type="text" [(ngModel)]="model.name" />

让我们尝试在我们的测试应用程序中使用ngModel

AppModule中配置FormsModule (src/app/app.module.ts)

import { FormsModule } from '@angular/forms'; @NgModule({ 
   imports: [ 
      BrowserModule, 
      FormsModule
   ] 
}) 
export class AppModule { }

FormModule进行必要的设置以启用双向数据绑定。

更新TestComponent视图(test.component.html),如下所述 -

<input type="text" [(ngModel)]="userName" />
<p>Two way binding! Hello {{ userName }}!</p>

这里,

属性绑定到表单控件ngModel指令,如果您在文本框中输入任何文本,它将绑定到该属性。运行应用程序后,您可以看到以下变化 -

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

数据绑定方式

现在,尝试将输入值更改为Jack。当您键入时,输入下方的文本会发生变化,最终输出将如下所示 -

双向数据绑定

我们将在接下来的章节中了解有关表单控件的更多信息。

工作示例

让我们在ExpenseManager应用程序中实现本章学到的所有概念。

打开命令提示符并转到项目根文件夹。

cd /go/to/expense-manager

创建 ExpenseEntry 接口 (src/app/expense-entry.ts) 并添加 id、amount、category、Location、spendOn 和createdOn。

export interface ExpenseEntry { 
   id: number; 
   item: string; 
   amount: number; 
   category: string; 
   location: string; 
   spendOn: Date; 
   createdOn: Date; 
}

ExpenseEntry导入ExpenseEntryComponent

import { ExpenseEntry } from '../expense-entry';

创建一个ExpenseEntry对象,expenseEntry如下所示 -

export class ExpenseEntryComponent implements OnInit { 
   title: string; 
   expenseEntry: ExpenseEntry; 
   constructor() { } 
   ngOnInit() { 
      this.title = "Expense Entry"; 
      this.expenseEntry = { 
         id: 1, 
         item: "Pizza", 
         amount: 21, 
         category: "Food", 
         location: "Zomato", 
         spendOn: new Date(2020, 6, 1, 10, 10, 10), createdOn: new Date(2020, 6, 1, 10, 10, 10), 
      }; 
   } 
}

使用ExpenseEntry对象src/app/expense-entry/expense-entry.component.html更新组件模板,如下所示 -

<!-- Page Content --> 
<div class="container">
   <div class="row"> 
      <div class="col-lg-12 text-center" style="padding-top: 20px;"> 
         <div class="container" style="padding-left: 0px; padding-right: 0px;"> 
            <div class="row"> 
               <div class="col-sm" style="text-align: left;"> 
                  {{ title }} 
               </div> 
               <div class="col-sm" style="text-align: right;"> 
                  <button type="button" class="btn btn-primary">Edit</button> 
               </div> 
            </div> 
         </div> 
         <div class="container box" style="margin-top: 10px;"> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;">  
                  <strong><em>Item:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.item }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Amount:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;">
                  {{ expenseEntry.amount }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Category:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.category }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;"> 
                  <strong><em>Location:</em></strong> 
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.location }} 
               </div> 
            </div> 
            <div class="row"> 
               <div class="col-2" style="text-align: right;">
                  <strong><em>Spend On:</em></strong>
               </div> 
               <div class="col" style="text-align: left;"> 
                  {{ expenseEntry.spendOn }} 
               </div> 
            </div> 
         </div> 
      </div> 
   </div> 
</div>
NG模型

Angular 8 - 指令

Angular 8 指令是与应用程序交互的 DOM 元素。一般来说,指令是一个TypeScript函数。当这个函数执行时,Angular编译器会在 DOM 元素中检查它。Angular 指令以ng-开头,其中ng代表 Angular,并使用@directive装饰器扩展 HTML 标签。

指令使逻辑能够包含在 Angular 模板中。Angular 指令可以分为三类,如下所示:

属性指令

用于为现有 HTML 元素添加新属性以更改其外观和Behave。

<HTMLTag [attrDirective]='value' />

例如,

<p [showToolTip]='Tips' />

这里,showToolTip引用了一个示例指令,当在 HTML 元素中使用该指令时,当用户将鼠标悬停在 HTML 元素上时将显示提示。

结构指令

用于在当前 HTML 文档中添加或删除 DOM 元素。

<HTMLTag [structuralDirective]='value' />

例如,

<div *ngIf="isNeeded"> 
   Only render if the *isNeeded* value has true value. 
</div>

这里,ngIf是一个内置指令,用于在当前HTML文档中添加或删除HTML元素。Angular 提供了许多内置指令,我们将在后面的章节中学习。

基于组件的指令

组件可以用作指令。每个组件都有输入输出选项,用于在组件与其父级 HTML 元素之间传递。

<component-selector-name [input-reference]="input-value"> ... </component-selector-name>

例如,

<list-item [items]="fruits"> ... </list-item>

这里,list-item是一个组件,items是输入选项。我们将在后面的章节中学习如何创建组件和高级用法。

在进入本主题之前,让我们在 Angular 8 中创建一个示例应用程序(directive-app)来学习知识。

打开命令提示符并使用以下命令创建新的 Angular 应用程序 -

cd /go/to/workspace 
ng new directive-app 
cd directive-app

使用 Angular CLI创建一个测试组件,如下所述 -

ng generate component test

上面创建了一个新组件,输出如下 -

CREATE src/app/test/test.component.scss (0 bytes) CREATE src/app/test/test.component.html (19 bytes) CREATE src/app/test/test.component.spec.ts (614 bytes) 
CREATE src/app/test/test.component.ts (262 bytes) UPDATE src/app/app.module.ts (545 bytes)

使用以下命令运行应用程序 -

ng serve

DOM 概述

让我们简单看一下 DOM 模型。DOM 用于定义访问文档的标准。一般来说,HTML DOM 模型被构造为对象树。它是访问 html 元素的标准对象模型。

我们可以在 Angular 8 中使用 DOM 模型,原因如下:

  • 我们可以使用 DOM 元素轻松导航文档结构。
  • 我们可以轻松添加 html 元素。
  • 我们可以轻松更新元素及其内容。

结构指令

结构指令通过添加或删除元素来更改DOM的结构。它由 * 符号表示,具有三个预定义指令NgIf、NgForNgSwitch。我们来简单的一一了解一下。

NgIf指令

NgIf指令用于根据条件为真或假来显示或隐藏应用程序中的数据。我们可以将其添加到模板中的任何标签中。

让我们在指令应用程序中尝试ngIf指令。

在test.component.html中添加以下标签。

<p>test works!</p> 
<div *ngIf="true">Display data</div>

在app.component.html文件中添加测试组件,如下所示 -

<app-test></app-test>

使用以下命令启动服务器(如果尚未启动) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

服务

如果设置条件ngIf=“false”那么内容将被隐藏。

ngIfElse 指令

ngIfElse与ngIf类似,但它也提供了在失败情况下渲染内容的选项。

让我们通过一个示例来了解ngIfElse 的工作原理。

在test.component.ts文件中添加以下代码。

export class TestComponent implements OnInit { 
   isLogIn : boolean = false;
   isLogOut : boolean = true; 
}

在test.component.html文件中添加以下代码,如下所示 -

<p>ngIfElse example!</p> 
<div *ngIf="isLogIn; else isLogOut"> 
   Hello you are logged in 
</div>
<ng-template #isLogOut> 
   You're logged out.. 
</ng-template>

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

NG应用程序

这里,

是注销

value 被指定为true,因此它会转到else块并呈现ng-template。我们将在本章后面学习ng-template 。

ngFor 指令

ngFor 用于重复项目列表中的一部分元素。

让我们通过一个示例来了解 ngFor 的工作原理。

在 test.component.ts 文件中添加列表,如下所示 -

list = [1,2,3,4,5];

在test.component.html中添加ngFor指令,如下所示 -

<h2>ngFor directive</h2> 
<ul> 
   <li *ngFor="let l of list">
      {{l}} 
   </li>
</ul>

在这里,let 关键字创建一个局部变量,可以在模板中的任何位置引用它。let l 创建一个模板局部变量来获取列表元素。

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

NG指令

音轨

有时,对于大型列表, ngFor性能较低。例如,当添加新项目或删除列表中的任何项目时可能会触发多个 DOM 操作。为了迭代大型对象集合,我们使用trackBy

它用于跟踪何时添加或删除元素。它是通过 trackBy 方法执行的。它有两个参数索引和元素。索引用于唯一地标识每个元素。简单的例子定义如下。

让我们通过一个示例来了解 trackBy 如何与ngFor一起工作。

在test.component.ts文件中添加以下代码。

export class TestComponent { 
   studentArr: any[] = [ { 
      "id": 1, 
      "name": "student1" 
   }, 
   { 
      "id": 2,
      "name": "student2" 
   }, 
   { 
      "id": 3, "name": "student3"
   },
   { 
      "id": 4, 
      "name": "student4" 
   } 
   ]; 
   trackByData(index:number, studentArr:any): number { 
      return studentArr.id; 
   }

这里,

我们创造了,

trackByData()

方法根据 id 以独特的方式访问每个学生元素。

在test.component.html文件中添加以下代码以在 ngFor 中定义 trackBy 方法。

<ul> 
   <li *ngFor="let std of studentArr; trackBy: trackByData">
      {{std.name}} 
   </li>
</ul>

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

指示

在这里,应用程序将打印学生姓名。现在,应用程序使用学生 ID 而不是对象引用来跟踪学生对象。因此,DOM 元素不受影响。

NgSwitch 指令

NgSWitch用于检查多个条件并保持 DOM 结构简单易懂。

让我们在指令应用程序中尝试ngSwitch指令。

在test.component.ts文件中添加以下代码。

export class TestComponent implements OnInit {  
   logInName = 'admin'; 
}

在 test.component.html 文件中添加以下代码,如下所示 -

<h2>ngSwitch directive</h2> 
<ul [ngSwitch]="logInName"> 
   <li *ngSwitchCase="'user'"> 
      <p>User is logged in..</p> 
   </li> 
   <li *ngSwitchCase="'admin'"> 
      <p>admin is logged in</p> 
   </li> 
   <li *ngSwitchDefault> 
      <p>Please choose login name</p> 
   </li> 
</ul>

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

NG开关

在这里,我们将logInName定义为admin。因此,它匹配第二个 SwitchCase 并打印上面的管理相关消息。

属性指令

属性指令执行 DOM 元素或组件的外观或Behave。其中一些示例包括 NgStyle、NgClass 和 NgModel。而 NgModel 是前一章中解释的双向属性数据绑定。

ng风格

ngStyle指令用于添加动态样式。下面的示例用于将蓝色应用于段落。

让我们在指令应用程序中尝试ngStyle指令。

在test.component.html文件中添加以下内容。

<p [ngStyle]="{'color': 'blue', 'font-size': '14px'}"> 
   paragraph style is applied using ngStyle 
</p>

使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

ng风格

ng类

ngClass用于在 HTML 元素中添加或删除 CSS 类。

让我们在指令应用程序中尝试ngClass指令。

使用以下命令创建一个用户类

ng g class User

您可以看到以下响应 -

CREATE src/app/user.spec.ts (146 bytes) 
CREATE src/app/user.ts (22 bytes)

移至src/app/user.ts文件并添加以下代码 -

export class User { 
   userId : number; userName : string; 
}

在这里,我们在User类中创建了两个属性userIduserName

打开test.component.ts文件并添加以下更改 -

import { User } from '../user'; 
export class TestComponent implements OnInit {  
   users: User[] = [ 
      { 
         "userId": 1, 
         "userName": 'User1' 
      }, 
      { 
         "userId": 2, 
         "userName": 'User2' 
      }, 
   ]; 
}

在这里,我们声明了一个局部变量 users 并用 2 个用户对象进行初始化。

打开test.component.css文件并添加以下代码

.highlight { 
   color: red; 
}

打开test.component.html文件并添加以下代码 -

<div class="container"> 
   <br/> 
   <div *ngFor="let user of users" [ngClass]="{ 
      'highlight':user.userName === 'User1' 
   }"> 
      {{ user.userName }} 
   </div> 
</div>

这里,

我们已经为User1应用了ngClass,因此它将突出显示User1

最后,使用以下命令启动您的应用程序(如果尚未完成) -

ng serve

现在,运行您的应用程序,您可以看到以下响应 -

ng类

自定义指令

Angular 提供了使用用户定义的指令来扩展 Angular 指令的选项,它被称为自定义指令。让我们在本章中学习如何创建自定义指令。

让我们尝试在指令应用程序中创建自定义指令。

Angular CLI 提供了以下命令来创建自定义指令。

ng generate directive customstyle

执行此命令后,您可以看到以下响应 -