Angular 6 快速指南



Angular 6 - 概述

Angular 有五个主要版本。第一个发布的版本是 Angular 1,也称为 AngularJS。Angular 1 之后是 Angular 2,与 Angular 1 相比,它带来了很多变化。

Angular 的结构基于组件/服务架构。AngularJS 基于模型视图控制器。Angular 6 于 2018 年 5 月发布,被证明是一项重大突破,是 Angular 团队在 Angular 5 之后发布的最新版本。

Angular 6 几乎与 Angular 5 相同。它与 Angular 5 向后兼容。使用 Angular 5 开发的项目可以在 Angular 5 中无任何问题地运行。

现在让我们看看 Angular 5 中的新功能和更改。

Angular 5 及其功能

Angular 5 于 2017 年 11 月发布。根据其速度和大小的目标,它比 Angular 4 更快,体积更小。以下是 Angular 5 中引入的功能。

  • HTTPClient API - 引入了 HTTPClient API 以弃用 HTTP 库。HTTPClient API 比 HTTP 库更快、更安全、更高效。

  • 多个导出别名 - 组件可以使用多个别名导出,以简化迁移过程。

  • 数字、日期和货币的国际化管道 - 引入了新的管道以实现更好的标准化。

  • Lambda 支持 - 可以使用具有正确名称的 lambda 表达式代替函数。

  • 构建优化器 - 引入构建优化器。它优化构建大小并提高应用程序速度。Angular CLI 自动使用构建优化器。

  • 改进的编译器 - 从 Angular 5 开始,编译器支持增量编译,从而实现更快的编译速度。编译器使用 TypeScript 转换,这是从 TypeScript 2.3 开始提供的新功能。

现在让我们看看添加到 Angular 6 中的新功能 -

  • 更新的 Angular CLI,命令行界面 - 添加了新命令,例如 ng-update 用于从旧版本迁移到当前版本。ng-add 用于快速添加应用程序功能,使应用程序成为渐进式 Web 应用程序。

  • 更新的 CDK,组件开发工具包 - 支持创建自定义 UI 元素,而无需 Angular Material 库。支持响应式网页设计布局。支持覆盖包以创建弹出窗口。

  • 更新的 Angular Material - 添加了新的树组件 mat-tree(带样式的版本)和 cdk-tree(无样式的版本),以表示树状的分层结构。

  • 使用 RxJS,一个响应式 JS 库

  • Angular Element - 允许将 Angular 组件发布为 Web 组件,然后可以在任何 HTML 页面中使用。使用 Angular Element 包,可以轻松创建原生自定义元素。

  • 多个验证器 - 允许在表单构建器上应用多个验证器。

  • 服务上的树形抖动 - 现在也可以对服务应用树形抖动以删除死代码。

Angular 6 - 环境设置

在本章中,我们将讨论 Angular 6 所需的环境设置。要安装 Angular 6,我们需要以下内容 -

  • Nodejs
  • Npm
  • Angular CLI
  • 用于编写代码的 IDE

Nodejs 必须大于 8.11,npm 必须大于 5.6。

Nodejs

要检查系统中是否安装了 nodejs,请在终端中键入node -v。这将帮助您查看当前安装在系统上的 nodejs 版本。

C:\>node -v
v8.11.3

如果它没有打印任何内容,请在您的系统上安装 nodejs。要安装 nodejs,请访问 nodejs 的主页https://node.org.cn/en/download/ 并根据您的操作系统安装软件包。

nodejs 的主页如下所示 -

NodeJS Homepage

根据您的操作系统,安装所需的软件包。安装 nodejs 后,npm 也会随之安装。要检查 npm 是否已安装,请在终端中键入 npm -v。它应该显示 npm 的版本。

C:\>npm -v
5.6.0

借助 angular CLI,Angular 4 的安装非常简单。访问 angular 的主页https://cli.angular.io/ 以获取命令的参考。

Angular CLI

键入npm install -g @angular/cli,以在您的系统上安装 angular cli。

Install Angular CLI

安装 Angular CLI 后,您将在终端中获得上述安装信息。您可以使用任何您选择的 IDE,例如 WebStorm、Atom、Visual Studio Code 等。

项目设置的详细信息将在下一章中说明。

Angular 6 - 项目设置

AngularJS 基于模型视图控制器,而 Angular 4 基于组件结构。Angular 6 使用与 Angular 4 相同的结构,但与 Angular 4 相比速度更快。

Angular 6 使用 TypeScript 2.9 版本,而 Angular 4 使用 TypeScript 2.2 版本。这在性能方面带来了很大的差异。

为了安装 Angular 6,Angular 团队推出了 Angular CLI,它简化了安装过程。您需要运行几个命令才能安装 Angular 6。

访问此站点https://cli.angular.io 以安装 Angular CLI。

Angular CLI

要开始安装,我们首先需要确保已安装最新版本的 nodejs 和 npm。npm 包与 nodejs 一起安装。

访问 nodejs 网站https://node.org.cn/en/

Download NodeJs

建议用户使用最新版本的 Nodejs v8.11.3。已经拥有大于 8.11 的 nodejs 的用户可以跳过上述过程。安装 nodejs 后,您可以使用命令 node -v 在命令行中检查 node 的版本,如下所示 -

node -v
v8.11.3

命令提示符显示 v8.11.3。安装 nodejs 后,npm 也会随之安装。

要检查 npm 的版本,请在终端中键入命令npm -v。它将显示 npm 的版本,如下所示。

npm -v
v5.6.0

npm 的版本为 5.6.0。现在我们已经安装了 nodejs 和 npm,让我们运行 angular cli 命令来安装 Angular 6。您将在网页上看到以下命令 -

npm install -g @angular/cli //command to install angular 6
ng new Angular 6-app // name of the project
cd my-dream-app
ng serve

让我们从命令行中的第一个命令开始,看看它是如何工作的。

首先,我们将创建一个空目录,在其中我们将运行 Angular CLI 命令。

npm install -g @angular/cli //command to install angular 6

我们创建了一个空文件夹ProjectA4并安装了 Angular CLI 命令。我们还使用了-g 将 Angular CLI 全局安装。现在,您可以在任何目录或文件夹中创建您的 Angular 4 项目,并且不必按项目安装 Angular CLI,因为它已全局安装在您的系统上,并且您可以从任何目录使用它。

现在让我们检查 Angular CLI 是否已安装。要检查安装,请在终端中运行以下命令 -

ng -v
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / ? \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 6.1.3
Node: 8.11.3
OS: win32 x64
Angular:
...

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.7.3
@angular-devkit/core         0.7.3
@angular-devkit/schematics   0.7.3
@schematics/angular          0.7.3
@schematics/update           0.7.3
rxjs                         6.2.2
typescript                   2.9.2

我们获得了 @angular/cli 版本,目前为 6.1.3。正在运行的节点版本为 8.11.3,以及操作系统详细信息。上述详细信息告诉我们我们已成功安装 angular cli,现在我们已准备好开始我们的项目。

我们现在已经安装了 Angular 6。现在让我们在 Angular 6 中创建我们的第一个项目。要在 Angular 6 中创建项目,我们将使用以下命令 -

ng new projectname

我们将项目命名为ng new Angular6App

现在让我们在命令行中运行上述命令。

ng new Angular6App
CREATE Angular6App/angular.json (3593 bytes)
CREATE Angular6App/package.json (1317 bytes)
CREATE Angular6App/README.md (1028 bytes)
CREATE Angular6App/tsconfig.json (408 bytes)
CREATE Angular6App/tslint.json (2805 bytes)
CREATE Angular6App/.editorconfig (245 bytes)
CREATE Angular6App/.gitignore (503 bytes)
CREATE Angular6App/src/favicon.ico (5430 bytes)
CREATE Angular6App/src/index.html (298 bytes)
CREATE Angular6App/src/main.ts (370 bytes)
CREATE Angular6App/src/polyfills.ts (3194 bytes)
CREATE Angular6App/src/test.ts (642 bytes)
CREATE Angular6App/src/styles.css (80 bytes)
CREATE Angular6App/src/browserslist (375 bytes)
CREATE Angular6App/src/karma.conf.js (964 bytes)
CREATE Angular6App/src/tsconfig.app.json (170 bytes)
CREATE Angular6App/src/tsconfig.spec.json (256 bytes)
CREATE Angular6App/src/tslint.json (314 bytes)
CREATE Angular6App/src/assets/.gitkeep (0 bytes)
CREATE Angular6App/src/environments/environment.prod.ts (51 bytes)
CREATE Angular6App/src/environments/environment.ts (642 bytes)
CREATE Angular6App/src/app/app.module.ts (314 bytes)
CREATE Angular6App/src/app/app.component.html (1141 bytes)
CREATE Angular6App/src/app/app.component.spec.ts (1010 bytes)
CREATE Angular6App/src/app/app.component.ts (215 bytes)
CREATE Angular6App/src/app/app.component.css (0 bytes)
CREATE Angular6App/e2e/protractor.conf.js (752 bytes)
CREATE Angular6App/e2e/tsconfig.e2e.json (213 bytes)
CREATE Angular6App/e2e/src/app.e2e-spec.ts (307 bytes)
CREATE Angular6App/e2e/src/app.po.ts (208 bytes)

项目Angular6App已成功创建。它安装了项目在 Angular 6 中运行所需的所有必需软件包。现在让我们切换到已创建的项目,该项目位于Angular6App目录中。在命令行中更改目录 - cd Angular 6-app

我们将使用 Visual Studio Code IDE 来处理 Angular 6;您可以使用任何 IDE,例如 Atom、WebStorm 等。

要下载 Visual Studio Code,请访问https://vscode.js.cn/ 并点击下载 Windows 版

Visual Studio Code

点击下载 Windows 版以安装 IDE 并运行安装程序以开始使用 IDE。

编辑器如下所示 -

Angular CLI Editor

我们还没有在其中启动任何项目。现在让我们使用 angular-cli 创建的项目。

Angular6App Project

现在我们有了项目的文件夹结构,让我们使用以下命令编译我们的项目 -

ng serve

ng serve命令构建应用程序并启动 Web 服务器。

** Angular Live Development Server is listening on localhost:4200, open your browser on https://:4200/ **
...
Date: 2018-08-18T11:17:54.745Z
Hash: 0ace6c8a055c58d1734c
Time: 20490ms
chunk {main} main.js, main.js.map (main) 10.7 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.6 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 3.27 MB [initial] [rendered]
i ?wdm?: Compiled successfully.

Web 服务器在端口 4200 上启动。在浏览器中键入 urlhttps://:4200/并查看输出。您将被定向到以下屏幕 -

Angular App

现在让我们进行一些更改以显示以下内容 -

"欢迎使用 Angular 6 项目"

Angular 6 Project

我们对文件 - app.component.htmlapp.component.ts进行了更改。我们将在后续章节中详细讨论。

让我们完成项目设置。如果您看到我们使用了端口 4200,这是 angular-cli 在编译时使用的默认端口。如果需要,您可以使用以下命令更改端口 -

ng serve --host 0.0.0.0 -port 4205

Angular 6 应用程序文件夹具有以下文件夹结构 -

  • e2e - 端到端测试文件夹。主要使用 e2e 进行集成测试,并帮助确保应用程序正常工作。

  • node_modules - 安装的 npm 包为 node_modules。您可以打开文件夹并查看可用的软件包。

  • src - 我们将在其中使用 Angular 4 处理项目的文件夹。

Angular 6 应用文件夹具有以下文件结构 -

  • .angular-cli.json - 它主要保存项目名称、cli 版本等信息。

  • .editorconfig - 这是编辑器的配置文件。

  • .gitignore - 为了与克隆存储库的任何其他用户共享忽略规则,应将 .gitignore 文件提交到存储库中。

  • karma.conf.js - 这用于通过探针进行单元测试。karma.conf.js 文件中提供了项目所需的所有信息。

  • package.json - package.json 文件说明在运行 npm install 时将哪些库安装到 node_modules 中。

目前,如果您在编辑器中打开该文件,您将看到其中添加了以下模块。

"@angular/animations": "^6.1.0",
"@angular/common": "^6.1.0",
"@angular/compiler": "^6.1.0",
"@angular/core": "^6.1.0",
"@angular/forms": "^6.1.0",
"@angular/http": "^6.1.0",
"@angular/platform-browser": "^6.1.0",
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"core-js": "^2.5.4",
"rxjs": "^6.0.0",
"zone.js": "~0.8.26"

如果您需要添加更多库,可以在这里添加它们并运行 npm install 命令。

  • protractor.conf.js - 这是应用程序所需的测试配置。

  • tsconfig.json - 这基本上包含编译期间所需的编译器选项。

  • tslint.json - 这是配置文件,其中包含编译时要考虑的规则。

src 文件夹是主文件夹,内部具有不同的文件结构

app

它包含下面描述的文件。这些文件默认由 angular-cli 安装。

  • app.module.ts - 如果您打开该文件,您将看到代码引用了导入的不同库。Angular-cli 使用了这些默认库进行导入 - angular/core、platform-browser。名称本身解释了库的用法。

它们被导入并保存到诸如declarations、imports、providersbootstrap之类的变量中。

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

declarations - 在 declarations 中,存储了对组件的引用。Appcomponent 是在启动新项目时创建的默认组件。我们将在另一部分学习创建新组件。

imports - 这将包含如上所示导入的模块。目前,BrowserModule 是 imports 的一部分,它从 @angular/platform-browser 导入。

providers - 这将引用创建的服务。服务将在后续章节中讨论。

bootstrap - 这引用了创建的默认组件,即 AppComponent。

  • app.component.css - 您可以在此处编写 css 结构。现在,我们已将背景颜色添加到 div 中,如下所示。

.divdetails{
   background-color: #ccc;
}
  • app.component.html - html 代码将在此文件中可用。

<!--The content below is only a placeholder and can be replaced.-->
<div class = "divdetails">
   <div style = "text-align:center">
      <h1>
         Welcome to {{title}}!
      </h1>
      <img width = "300" src =    "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNv
         ZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3Ry
         YXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9
         uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0i
         TGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4b
         Wxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB
         4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hY
         mxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmV
         zZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojR
         EQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZ
         GRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBva
         W50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjM
         gMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMi
         AJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1L
         DUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwy
         MzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGN
         sYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLj
         ctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuM
         UwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4b
         DE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
   </div>
   <h2>Here are some links to help you start: </h2>
   <ul>
      <li>
         <h2>
            <a target = "_blank" href="https://angular.io/tutorial">Tour of Heroes</a>
         </h2>
      </li>
      <li>
         <h2>
            <a target = "_blank" href = "https://github.com/angular/angular-cli/wiki">
               CLI Documentation
            </a>
         </h2>
      </li>
      <li>
         <h2>
            <a target = "_blank" href="http://angularjs.blogspot.ca/">Angular blog</a>
         </h2>
      </li>
   </ul>
</div>

这是项目创建时当前可用的默认 html 代码。

  • app.component.spec.ts - 这些是自动生成的文件,包含源组件的单元测试。

  • app.component.ts - 组件的类在此处定义。您可以在 .ts 文件中处理 html 结构。处理将包括连接到数据库、与其他组件交互、路由、服务等活动。

文件结构如下所示 -

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

Assets

您可以在此文件夹中保存图像、js 文件。

Environment

此文件夹包含生产或开发环境的详细信息。该文件夹包含两个文件。

  • environment.prod.ts
  • environment.ts

这两个文件都包含最终文件是否应在生产环境或开发环境中编译的详细信息。

Angular 4 应用文件夹的其他文件结构包括以下内容 -

favicon.ico

这是一个通常位于网站根目录的文件。

index.html

这是在浏览器中显示的文件。

<!doctype html>
<html lang = "en">
   <head>
      <meta charset = "utf-8">
      <title>HTTP Search Param</title>
      <base href = "/">
      <link href = "https://fonts.googleapis.ac.cn/icon?family=Material+Icons" rel = "stylesheet">
      <link href = "https://fonts.googleapis.ac.cn/css?family=Roboto|Roboto+Mono" rel = "stylesheet">
      <link href = "styles.c7c7b8bf22964ff954d3.bundle.css" rel = "stylesheet">
      <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-root></app-root>。这是在app.component.ts文件中使用的选择器,并将显示来自 app.component.html 文件的详细信息。

main.ts

main.ts 是我们从那里开始项目开发的文件。它从导入我们需要的基本模块开始。现在,如果您看到 angular/core、angular/platform-browser-dynamic、app.module 和 environment,它们在 angular-cli 安装和项目设置期间默认导入。

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);

platformBrowserDynamic().bootstrapModule(AppModule)具有父模块引用AppModule。因此,当它在浏览器中执行时,调用的文件是 index.html。Index.html 内部引用 main.ts,当以下代码执行时,它调用父模块,即 AppModule -

platformBrowserDynamic().bootstrapModule(AppModule);

当调用 AppModule 时,它会调用 app.module.ts,后者根据引导进一步调用 AppComponent,如下所示 -

bootstrap: [AppComponent]

在 app.component.ts 中,有一个selector: app-root,它用于 index.html 文件中。这将显示 app.component.html 中存在的内容。

浏览器中将显示以下内容 -

App Module

polyfill.ts

这主要用于向后兼容性。

styles.css

这是项目所需的样式文件。

test.ts

在这里,将处理用于测试项目的单元测试用例。

tsconfig.app.json

这在编译期间使用,它具有运行应用程序需要使用的配置详细信息。

tsconfig.spec.json

这有助于维护测试详细信息。

typings.d.ts

它用于管理 TypeScript 定义。

Angular 6 - 组件

使用 Angular 6 进行的大部分开发都在组件中完成。组件基本上是与组件的 .html 文件交互的类,该文件显示在浏览器上。我们在前面的一章中看到了文件结构。文件结构具有 app 组件,它包含以下文件 -

  • app.component.css

  • app.component.html

  • app.component.spec.ts

  • app.component.ts

  • app.module.ts

当我们使用 angular-cli 命令创建新项目时,上述文件是默认创建的。

如果您打开app.module.ts文件,它会导入一些库,并且还分配了 appcomponent 的声明,如下所示 -

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

declarations 包括我们已导入的 AppComponent 变量。这成为父组件。

现在,angular-cli 有一个命令来创建您自己的组件。但是,默认创建的 app 组件将始终保持为父组件,创建的下一个组件将形成子组件。

现在让我们运行命令来创建组件。

ng generate component new-cmp

当您在命令行中运行上述命令时,您将收到以下输出 -

D:\Node\Angular6App>ng generate component new-cmp
CREATE src/app/new-cmp/new-cmp.component.html (26 bytes)
CREATE src/app/new-cmp/new-cmp.component.spec.ts (629 bytes)
CREATE src/app/new-cmp/new-cmp.component.ts (272 bytes)
CREATE src/app/new-cmp/new-cmp.component.css (0 bytes)
UPDATE src/app/app.module.ts (398 bytes)

现在,如果我们去检查文件结构,我们将看到在 src/app 文件夹下创建了新的 new-cmp 文件夹。

在 new-cmp 文件夹中创建了以下文件 -

  • new-cmp.component.css - 创建了新组件的 css 文件。

  • new-cmp.component.html - 创建了 html 文件。

  • new-cmp.component.spec.ts - 这可以用于单元测试。

  • new-cmp.component.ts - 在这里,我们可以定义模块、属性等。

对 app.module.ts 文件进行了如下更改 -

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
// includes the new-cmp component we created
@NgModule({
   declarations: [
      AppComponent,
      NewCmpComponent // here it is added in declarations and will behave as a child component
   ],
   imports: [
      BrowserModule
   ],
   providers: [],
   bootstrap: [AppComponent] //for bootstrap the AppComponent the main app component is given.
})

export class AppModule { }

new-cmp.component.ts 文件生成如下 -

import { Component, OnInit } from '@angular/core'; // here angular/core is imported .
@Component({
   // this is a declarator which starts with @ sign. The component word marked in bold needs to be the same.
   selector: 'app-new-cmp', //
   templateUrl: './new-cmp.component.html', 
   // reference to the html file created in the new component.
   styleUrls: ['./new-cmp.component.css'] // reference to the style file.
})
export class NewCmpComponent implements OnInit {
   constructor() { }
   ngOnInit() {}
}

如果您查看上面的 new-cmp.component.ts 文件,它会创建一个名为 NewCmpComponent 的新类,该类实现了 OnInit。其中包含一个构造函数和一个名为 ngOnInit() 的方法。当类执行时,默认会调用 ngOnInit。

让我们检查一下流程是如何工作的。现在,默认创建的 app 组件成为父组件。以后添加的任何组件都成为子组件。

当我们在https://:4200/浏览器中点击 url 时,它首先执行 index.html 文件,如下所示 -

<!doctype html>
<html lang = "en">
   <head>
      <meta charset = "utf-8">
      <title>Angular 6 Application</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>

以上是普通的 html 文件,我们没有看到任何打印在浏览器中的内容。看看 body 部分中的标签。

<app-root></app-root>

这是 Angular 默认创建的根标签。此标签在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);

AppModule 从主父模块的 app 中导入,并将相同的模块传递给 bootstrap Module,这使得 appmodule 加载。

现在让我们看看app.module.ts文件 -

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
@NgModule({
   declarations: [
      AppComponent,
      NewCmpComponent
   ],
   imports: [
      BrowserModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})

export class AppModule { }

在这里,AppComponent 是给定的名称,即存储app. Component.ts引用的变量,并将相同的变量传递给 bootstrap。现在让我们看看app.component.ts文件。

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

Angular core 被导入并作为 Component 引用,并在 Declarator 中使用,如下所示 -

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})

在 declarator 中,引用了选择器、templateUrlstyleUrl。此处的选择器只不过是我们上面看到的 index.html 文件中放置的标签。

类 AppComponent 有一个名为 title 的变量,它显示在浏览器中。

@Component使用名为 app.component.html 的 templateUrl,如下所示 -

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>

它只有 html 代码和花括号中的变量 title。它将被替换为app.component.ts文件中存在的 value。这称为绑定。我们将在后续章节中讨论绑定的概念。

现在我们已经创建了一个名为new-cmp的新组件。当运行创建新组件的命令时,相同的组件会被包含在app.module.ts文件中。

app.module.ts引用了创建的新组件。

现在让我们检查在 new-cmp 中创建的新文件。

new-cmp.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
   selector: 'app-new-cmp',
   templateUrl: './new-cmp.component.html',
   styleUrls: ['./new-cmp.component.css']
})
export class NewCmpComponent implements OnInit {
   constructor() { }
   ngOnInit() {}
}

在这里,我们还必须导入 core。组件的引用在 declarator 中使用。

declarator 具有名为app-new-cmp的选择器以及templateUrlstyleUrl

名为new-cmp.component.html的 .html 如下所示 -

<p>
   new-cmp works!
</p>

如上所示,我们有 html 代码,即 p 标签。样式文件为空,因为我们目前不需要任何样式。但是,当我们运行项目时,我们没有看到任何与新组件相关的内容显示在浏览器中。现在让我们添加一些内容,稍后可以在浏览器中看到。

选择器,即app-new-cmp需要添加到app.component .html文件中,如下所示 -

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<app-new-cmp></app-new-cmp>

当添加<app-new-cmp></app-new-cmp>标签时,创建的新组件的 .html 文件中存在的所有内容都将与父组件数据一起显示在浏览器上。

让我们看看新组件 .html文件和new-cmp.component.ts文件。

new-cmp.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
   selector: 'app-new-cmp',
   templateUrl: './new-cmp.component.html',
   styleUrls: ['./new-cmp.component.css']
})
export class NewCmpComponent implements OnInit {
   newcomponent = "Entered in new component created";
   constructor() {}
   ngOnInit() { }
}

在类中,我们添加了一个名为 new component 的变量,其值为“Entered in new component created”。

上述变量在.new-cmp.component.html文件中绑定如下:

<p>
   {{newcomponent}}
</p>
<p>
   new-cmp works!
</p>

现在,由于我们在父组件的app.component.html文件中包含了<app-new-cmp></app-new-cmp>选择器,因此新组件.html文件(new-cmp.component.html)中的内容将在浏览器中显示如下:

Using Selectors Browser Output

类似地,我们可以根据需要创建组件并在app.component.html文件中使用选择器链接它们。

Angular 6 - 模块

Angular中的模块指的是一个可以将与应用程序相关的组件、指令、管道和服务分组的地方。

如果您正在开发一个网站,则标题、页脚、左侧、中心和右侧部分将成为模块的一部分。

要定义模块,我们可以使用NgModule。当您使用Angular-cli命令创建新项目时,ngmodule默认情况下会在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 { }

NgModule需要导入如下:

import { NgModule } from '@angular/core';

ngmodule的结构如下所示:

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

它以@NgModule开头,并包含一个具有declarations、imports、providers和bootstrap的对象。

声明(Declaration)

它是一个创建的组件数组。如果创建了任何新组件,它将首先被导入,并且引用将包含在declarations中,如下所示:

declarations: [
   AppComponent,
   NewCmpComponent
]

导入(Import)

它是一个应用程序中需要使用的模块数组。它也可以被Declaration数组中的组件使用。例如,现在在@NgModule中,我们看到导入了BrowserModule。如果您的应用程序需要表单,您可以包含以下模块:

import { FormsModule } from '@angular/forms';

@NgModule中的导入将如下所示:

imports: [
   BrowserModule,
   FormsModule
]

提供程序(Providers)

这将包括创建的服务。

引导(Bootstrap)

这包括用于启动执行的主应用程序组件。

Angular 6 - 数据绑定

数据绑定从AngularJS、Angular 2、4开始就可用,现在在Angular 6中也可用。我们使用花括号进行数据绑定 - {{}}; 这个过程称为插值。我们已经在之前的示例中看到了如何将值声明为变量title,以及如何在浏览器中打印它。

app.component.html文件中的变量被称为{{title}},title的值在app.component.ts文件中初始化,在app.component.html中显示该值。

现在让我们在浏览器中创建一个月份下拉列表。为此,我们在app.component.ts中创建了一个月份数组,如下所示:

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   // declared array of months.
   months = ["January", "Feburary", "March", "April", "May", 
            "June", "July", "August", "September",
            "October", "November", "December"];
}

上面显示的月份数组需要在浏览器中的下拉列表中显示。为此,我们将使用以下代码行:

<!--The content below is only a placeholder and can be replaced. -->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select>
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>

我们创建了带有选项的普通select标签。在option中,我们使用了for循环for循环用于遍历月份数组,这将依次创建具有月份中存在的值的option标签。

Angular中的语法for*ngFor = "let I of months",要获取月份的值,我们在{{i}}中显示它。

两个花括号有助于数据绑定。您在app.component.ts文件中声明变量,并且将使用花括号替换相同的变量。

让我们看看上述月份数组在浏览器中的输出

Output Month's Array in Browser

app.component.ts中设置的变量可以使用花括号绑定到app.component.html;例如,{{}}

现在让我们根据条件在浏览器中显示数据。在这里,我们添加了一个变量并将值设置为true。使用if语句,我们可以隐藏/显示要显示的内容。

示例

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 4 Project!';
   //array of months.
   months = ["January", "February", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   isavailable = true;   //variable is set to true
}

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select>
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable">Condition is valid.</span> 
  <!--over here based on if condition the text condition is valid is displayed. 
  If the value of isavailable is set to false it will not display the text.-->
</div>

输出

Output Using IF-Statement

让我们尝试使用IF THEN ELSE条件使用上述示例。

示例

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 4 Project!';
   //array of months.
   months = ["January", "February", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   isavailable = false;
}

在这种情况下,我们将isavailable变量设置为false。要打印else条件,我们将不得不创建ng-template,如下所示:

<ng-template #condition1>Condition is invalid</ng-template>

完整的代码如下所示:

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select>
      <option *ngFor="let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable; else condition1">Condition is valid.</span>
   <ng-template #condition1>Condition is invalid</ng-template>
</div>

If与else条件一起使用,使用的变量是condition1。它被分配为ng-templateid,当available变量设置为false时,将显示文本Condition is invalid

以下屏幕截图显示了浏览器中的显示。

Output Using If-Else Condition

现在让我们使用if then else条件。

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 4 Project!';
   //array of months.
   months = ["January", "February", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   isavailable = true;
}

现在,我们将变量isavailable设置为true。在html中,条件以以下方式编写:

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
   Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select>
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable; then condition1 else condition2">Condition is valid.</span>
   <ng-template #condition1>Condition is valid</ng-template>
   <ng-template #condition2>Condition is invalid</ng-template>
</div>

如果变量为true,则condition1,否则condition2。现在,使用id#condition1#condition2创建了两个模板。

浏览器中的显示如下:

Output Using IF-Statement

Angular 6 - 事件绑定

在本章中,我们将讨论事件绑定在Angular 6中是如何工作的。当用户以键盘移动、鼠标点击或鼠标悬停的形式与应用程序交互时,它会生成一个事件。需要处理这些事件以执行某种操作。这就是事件绑定发挥作用的地方。

让我们考虑一个例子来更好地理解这一点。

app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select>
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable; then condition1 else condition2">
      Condition is valid.
   </span>
   <ng-template #condition1>Condition is valid</ng-template>
   <ng-template #condition2>Condition is invalid</ng-template>
</div>
<button (click)="myClickFunction($event)">
   Click Me
</button>

app.component.html文件中,我们定义了一个按钮并使用click事件向其添加了一个函数。

以下是定义按钮并向其添加函数的语法。

(click)="myClickFunction($event)"

该函数在.ts文件中定义:app.component.ts

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   //array of months.
   months = ["January", "Feburary", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   isavailable = true;
   myClickFunction(event) { 
      //just added console.log which will display the event details in browser on click of the button.
      alert("Button is clicked");
      console.log(event);
   }
}

点击按钮后,控制权将转到函数myClickFunction,并将出现一个对话框,其中显示the Button is clicked,如下面的屏幕截图所示:

Output Using myClickFunction

现在让我们将change事件添加到下拉列表中。

以下代码行将帮助您将change事件添加到下拉列表中:

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select (change) = "changemonths($event)">
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable; then condition1 else condition2">
      Condition is valid.
   </span>
   <ng-template #condition1>Condition is valid</ng-template>
   <ng-template #condition2>Condition is invalid</ng-template>
</div>
<button (click) = "myClickFunction($event)">Click Me</button>

该函数在app.component.ts文件中声明:

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   //array of months.
   months = ["January", "Feburary", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   isavailable = true;
   myClickFunction(event) {
      alert("Button is clicked");
      console.log(event);
   }
   changemonths(event) {
      console.log("Changed month from the Dropdown");
      console.log(event);
   }
}

控制台消息“Changed month from the Dropdown”与事件一起显示在控制台中。

Changed Month From Dropdown

让我们在下拉列表的值更改时在app.component.ts中添加一个警报消息,如下所示:

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   //array of months.
   months = ["January", "February", "March", "April",
            "May", "June", "July", "August", "September",
            "October", "November", "December"];
   
   isavailable = true;
   myClickFunction(event) { 
      //just added console.log which will display the event details in browser 
      on click of the button.
      alert("Button is clicked");
      console.log(event);
   }
   changemonths(event) {
      alert("Changed month from the Dropdown");
   }
}

当下拉列表中的值更改时,将出现一个对话框,并将显示以下消息:“Changed month from the Dropdown”。

Changed Month From Dropdown2

Angular 6 - 模板

Angular 6使用<ng-template>作为标签,类似于Angular 4,而不是Angular 2中使用的<template>。Angular 4将<template>更改为<ng-template>的原因是<template>标签与html<template>标准标签之间存在名称冲突。它将在未来完全弃用。

现在让我们将模板与if else条件一起使用,并查看输出。

app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select (change) = "changemonths($event)" name = "month">
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable;then condition1 else condition2">Condition is valid.</span>
   <ng-template #condition1>Condition is valid from template</ng-template>
   <ng-template #condition2>Condition is invalid from template</ng-template>
</div>
<button (click) = "myClickFunction($event)">Click Me</button>

对于Span标签,我们添加了带有else条件的if语句,并将调用模板condition1,否则调用condition2。

模板需要调用如下:

<ng-template #condition1>Condition is valid from template</ng-template>
<ng-template #condition2>Condition is invalid from template</ng-template>

如果条件为真,则调用condition1模板,否则调用condition2。

app.component.ts

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   //array of months.
   months = ["January", "February", "March", "April",
      "May", "June", "July", "August", "September",
      "October", "November", "December"];
   isavailable = false;
   myClickFunction(event) {
      this.isavailable = false;
   }
   changemonths(event) {
      alert("Changed month from the Dropdown");
      console.log(event);
   }
}

浏览器中的输出如下:

App Component.ts Output

变量isavailable为false,因此打印condition2模板。如果您单击按钮,则将调用相应的模板。如果您检查浏览器,您会发现您永远不会在dom中获得span标签。以下示例将帮助您理解这一点。

Inspect The Browser

如果您检查浏览器,您会发现dom中没有span标签。它在dom中具有Condition is invalid from template

html中的以下代码行将帮助我们在dom中获取span标签。

<!--The content below is only a placeholder and can be replaced.-->
<div style = "text-align:center">
   <h1>
      Welcome to {{title}}.
   </h1>
</div>
<div> Months :
   <select (change) = "changemonths($event)" name = "month">
      <option *ngFor = "let i of months">{{i}}</option>
   </select>
</div>
<br/>
<div>
   <span *ngIf = "isavailable; else condition2">Condition is valid.</span>
   <ng-template #condition1>Condition is valid from template</ng-template>
   <ng-template #condition2>Condition is invalid from template</ng-template>
</div>
<button (click)="myClickFunction($event)">Click Me</button>

如果我们删除then条件,我们将在浏览器中获得"Condition is valid"消息,并且span标签也存在于dom中。例如,在app.component.ts中,我们将isavailable变量设置为true。

app.component.ts isavailable

Angular 6 - 指令

Angular中的指令是一个js类,它被声明为@directive。我们在Angular中有3个指令。指令列在下面:

组件指令

它们构成主类,其中包含有关如何在运行时处理、实例化和使用组件的详细信息。

结构指令

结构指令基本上处理操作dom元素。结构指令在指令前有一个*号。例如,*ngIf*ngFor

属性指令

属性指令处理更改dom元素的外观和行为。您可以创建自己的指令,如下所示。

如何创建自定义指令?

在本节中,我们将讨论将在组件中使用的自定义指令。自定义指令由我们创建,不是标准的。

让我们看看如何创建自定义指令。我们将使用命令行创建指令。使用命令行创建指令的命令是:

ng g directive nameofthedirective
e.g
ng g directive changeText

它在命令行中显示如下

C:\projectA6\Angular6App>ng g directive changeText
CREATE src/app/change-text.directive.spec.ts (241 bytes)
CREATE src/app/change-text.directive.ts (149 bytes)
UPDATE src/app/app.module.ts (486 bytes)

上述文件,即change-text.directive.spec.tschange-text.directive.ts被创建,并且app.module.ts文件被更新。

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
@NgModule({
   declarations: [
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

ChangeTextDirective类包含在上述文件中的declarations中。该类也从下面给出的文件中导入。

change-text.directive

import { Directive } from '@angular/core';
@Directive({
   selector: '[appChangeText]'
})
export class ChangeTextDirective {
   constructor() { }
}

上述文件包含一个指令,它还具有一个selector属性。我们在selector中定义的内容必须与我们在其中分配自定义指令的视图匹配。

app.component.html视图中,让我们添加指令如下:

<div style = "text-align:center">
   <span appChangeText >Welcome to {{title}}.</span>
</div>

我们将在change-text.directive.ts文件中编写更改,如下所示:

change-text.directive.ts

import { Directive, ElementRef} from '@angular/core';
@Directive({
   selector: '[appChangeText]'
})
export class ChangeTextDirective {
   constructor(Element: ElementRef) {
      console.log(Element);
      Element.nativeElement.innerText = "Text is changed by changeText Directive. ";
   }
}

在上述文件中,有一个名为ChangeTextDirective的类和一个构造函数,它接收类型为ElementRef的元素,这是必需的。该元素包含应用Change Text指令的所有详细信息。

我们添加了console.log元素。可以在浏览器控制台中看到它的输出。元素的文本也如上所示更改。

现在,浏览器将显示以下内容。

ChangeText Directive

Angular 6 - 管道

在本章中,我们将讨论Angular 6中的管道是什么。管道在Angular 1中以前称为过滤器,从Angular 2开始称为管道。

| 字符用于转换数据。以下是相同的语法

{{ Welcome to Angular 6 | lowercase}}

它接收整数、字符串、数组和日期作为输入,以|分隔,并将其转换为所需的格式,并在浏览器中显示。

让我们考虑一些使用管道符号的示例。

这里,我们希望将给定的文本显示为大写。这可以通过使用管道符号来实现,如下所示:

app.component.ts文件中,我们定义了title变量:

app.component.ts

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

以下代码行进入app.component.html文件。

<b>{{title | uppercase}}</b><br/>
<b>{{title | lowercase}}</b>

浏览器显示如下面的屏幕截图所示:

Uppercase Lowercase

Angular 6提供了一些内置管道。这些管道列出如下:

  • 小写管道
  • 大写管道
  • 日期管道
  • 货币管道
  • JSON管道
  • 百分比管道
  • 十进制管道
  • 切片管道

我们已经看到了小写和大写管道。现在让我们看看其他管道是如何工作的。

以下代码行将帮助我们在app.component.ts文件中定义所需的变量:

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate = new Date();
   jsonval = {name:'Rox', age:'25', address:{a1:'Mumbai', a2:'Karnataka'}};
   months = ["Jan", "Feb", "Mar", "April", "May", "Jun",
            "July", "Aug", "Sept", "Oct", "Nov", "Dec"];
}

我们将在app.component.html文件中使用这些管道。

<!--The content below is only a placeholder and can be replaced.-->
<div style = "width:100%;">
   <div style = "width:40%;float:left;border:solid 1px black;">
      <h1>Uppercase Pipe</h1>
      <b>{{title | uppercase}}</b><br/>
      <h1>Lowercase Pipe</h1>
      <b>{{title | lowercase}}</b>
      <h1>Currency Pipe</h1>
      <b>{{6589.23 | currency:"USD"}}</b><br/>
      <b>{{6589.23 | currency:"USD":true}}</b> //Boolean true is used to get the sign of the currency.
      <h1>Date pipe</h1>
      <b>{{todaydate | date:'d/M/y'}}</b><br/>
      <b>{{todaydate | date:'shortTime'}}</b>
      <h1>Decimal Pipe</h1>
      <b>{{ 454.78787814 | number: '3.4-4' }}</b> // 3 is for main integer, 4 -4 are for integers to be displayed.
   </div>
   <div style = "width:40%;float:left;border:solid 1px black;">
      <h1>Json Pipe</h1>
      <b>{{ jsonval | json }}</b>
      <h1>Percent Pipe</h1>
      <b>{{00.54565 | percent}}</b>
      <h1>Slice Pipe</h1>
      <b>{{months | slice:2:6}}</b> 
      // here 2 and 6 refers to the start and the end index
   </div>
</div>

以下屏幕截图显示了每个管道的输出:

Output For Each Pipe

Output For Each Pipe-2

如何创建自定义管道?

要创建自定义管道,我们创建了一个新的ts文件。这里,我们想要创建sqrt自定义管道。我们为文件指定了相同的名称,它看起来如下所示:

app.sqrt.ts

import {Pipe, PipeTransform} from '@angular/core';
@Pipe ({
   name : 'sqrt'
})
export class SqrtPipe implements PipeTransform {
   transform(val : number) : number {
      return Math.sqrt(val);
   }
}

要创建自定义管道,我们必须从Angular/core中导入Pipe和PipeTransform。在@Pipe指令中,我们必须为我们的管道命名,这将在我们的.html文件中使用。由于我们正在创建sqrt管道,因此我们将将其命名为sqrt。

随着我们继续,我们必须创建类,类名为SqrtPipe。此类将实现PipeTransform

在类中定义的transform方法将以数字作为参数,并在获取平方根后返回该数字。

由于我们创建了一个新文件,因此我们需要在app.module.ts中添加它。操作如下所示:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

我们创建了app.sqrt.ts类。我们必须在app.module.ts中导入它并指定文件路径。它也必须包含在声明中,如上所示。

现在让我们看看在app.component.html文件中对sqrt管道的调用。

<h1>Custom Pipe</h1>
<b>Square root of 25 is: {{25 | sqrt}}</b>
<br/>
<b>Square root of 729 is: {{729 | sqrt}}</b>

输出如下所示:

Custome Pipe

Angular 6 - 路由

路由基本上意味着在页面之间导航。您已经看到许多网站包含指向新页面的链接。这可以通过使用路由来实现。这里我们所指的页面将以组件的形式存在。我们已经看到了如何创建组件。现在让我们创建一个组件,并看看如何使用路由。

在主父组件app.module.ts中,我们现在必须包含路由模块,如下所示:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule} from '@angular/router';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule,
      RouterModule.forRoot([
         {
            path: 'new-cmp',
            component: NewCmpComponent
         }
      ])
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

import { RouterModule} from '@angular/router'

这里,RouterModule是从angular/router导入的。该模块包含在导入中,如下所示:

RouterModule.forRoot([
   {
      path: 'new-cmp',
      component: NewCmpComponent
   }
])

RouterModule引用forRoot,它以数组作为输入,数组又包含路径和组件的对象。路径是路由器的名称,组件是类的名称,即创建的组件。

现在让我们看看创建的组件文件:

New-cmp.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
   selector: 'app-new-cmp',
   templateUrl: './new-cmp.component.html',
   styleUrls: ['./new-cmp.component.css']
})
export class NewCmpComponent implements OnInit {
   newcomponent = "Entered in new component created";
   constructor() {}
   ngOnInit() { }
}

突出显示的类在主模块的导入中提到。

New-cmp.component.html

<p>
   {{newcomponent}}
</p>

<p>
   new-cmp works!
</p>

现在,我们需要在需要时或从主模块单击时显示html文件中的上述内容。为此,我们需要在app.component.html中添加路由详细信息。

<h1>Custom Pipe</h1>
<b>Square root of 25 is: {{25 | sqrt}}</b><br/>
<b>Square root of 729 is: {{729 | sqrt}}</b>
<br />
<br />
<br />
<a routerLink = "new-cmp">New component</a>
<br />
<br/>
<router-outlet></router-outlet>

在上面的代码中,我们创建了锚链接标签,并将routerLink设置为"new-cmp"。这在app.module.ts中被引用为路径。

当用户点击new component时,页面应该显示内容。为此,我们需要以下标签 - <router-outlet> </router-outlet>

上述标签确保当用户点击new component时,new-cmp.component.html中的内容将显示在页面上。

现在让我们看看输出如何在浏览器中显示。

Custome Pipe-1

当用户点击New component时,您将在浏览器中看到以下内容。

Custome Pipe-2

url包含https://:4200/new-cmp。这里,new-cmp被附加到原始url,这是在app.module.ts中给出的路径和app.component.html中的router-link。

当用户点击New component时,页面不会刷新,内容在没有重新加载的情况下显示给用户。只有在点击时,站点代码的特定部分才会重新加载。当页面上有大量内容并且需要根据用户交互加载时,此功能很有帮助。此功能还提供了良好的用户体验,因为页面不会重新加载。

Angular 6 - 服务

在本章中,我们将讨论Angular 6中的服务。

我们可能会遇到需要在页面上任何位置使用某些代码的情况。它可以用于需要在组件之间共享的数据连接等。服务帮助我们实现这一点。使用服务,我们可以访问整个项目中其他组件的各个方法和属性。

要创建服务,我们需要使用命令行。相应的命令是:

C:\projectA6\Angular6App>ng g service myservice
CREATE src/app/myservice.service.spec.ts (392 bytes)
CREATE src/app/myservice.service.ts (138 bytes)

文件在app文件夹中创建如下:

Files In App Folder

以下是底部创建的文件 - myservice.service.specs.tsmyservice.service.ts

myservice.service.ts

import { Injectable } from '@angular/core';
@Injectable()
export class MyserviceService {
   constructor() { }
}

这里,Injectable模块是从@angular/core导入的。它包含@Injectable方法和一个名为MyserviceService的类。我们将在此类中创建服务函数。

在创建新服务之前,我们需要在主父app.module.ts中包含创建的服务。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule} from '@angular/router';
import { AppComponent } from './app.component';
import { MyserviceService } from './myservice.service';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule,
      RouterModule.forRoot([
         {
            path: 'new-cmp',
            component: NewCmpComponent
         }
      ])
   ],
   providers: [MyserviceService],
   bootstrap: [AppComponent]
})
export class AppModule { }

我们已经导入了带有类名的服务,并在提供程序中使用了相同的类。现在让我们切换回服务类并创建一个服务函数。

在服务类中,我们将创建一个函数来显示今天的日期。我们可以在主父组件app.component.ts以及我们在上一章中创建的新组件new-cmp.component.ts中使用相同的函数。

现在让我们看看函数在服务中的样子以及如何在组件中使用它。

import { Injectable } from '@angular/core';
@Injectable()
export class MyserviceService {
   constructor() { }
   showTodayDate() {
      let ndate = new Date();
      return ndate;
   }
}

在上面的服务文件中,我们创建了一个函数showTodayDate。现在我们将返回创建的新Date()。让我们看看如何在组件类中访问此函数。

app.component.ts

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate;
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
   }
}

ngOnInit函数在创建的任何组件中默认调用。日期从服务中获取,如上所示。要获取服务的更多详细信息,我们需要首先在组件ts文件中包含该服务。

我们将在.html文件中显示日期,如下所示:

{{todaydate}}
<app-new-cmp></app-new-cmp> 
// data to be displayed to user from the new component class.

现在让我们看看如何在创建的新组件中使用服务。

import { Component, OnInit } from '@angular/core';
import { MyserviceService } from './../myservice.service';
@Component({
   selector: 'app-new-cmp',
   templateUrl: './new-cmp.component.html',
   styleUrls: ['./new-cmp.component.css']
})
export class NewCmpComponent implements OnInit {
   todaydate;
   newcomponent = "Entered in new component created";
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
   }
}

在我们创建的新组件中,我们需要首先导入我们想要的服务并访问其方法和属性。请参见突出显示的代码。todaydate在组件html中显示如下:

<p>
   {{newcomponent}}
</p>
<p>
   Today's Date : {{todaydate}}
</p>

新组件的选择器用于app.component.html文件中。来自上面html文件的内容将在浏览器中显示,如下所示:

Output New Component Created

如果您更改任何组件中服务的属性,则其他组件中的相同属性也会更改。现在让我们看看它是如何工作的。

我们将在服务中定义一个变量,并在父组件和新组件中使用它。我们将在父组件中再次更改变量的值,并查看它是否在新组件中也更改了。

myservice.service.ts中,我们创建了一个属性并在其他父组件和新组件中使用了它。

import { Injectable } from '@angular/core';
@Injectable()
export class MyserviceService {
   serviceproperty = "Service Created";
   constructor() { }
   showTodayDate() {
      let ndate = new Date();
      return ndate;
   }
}

现在让我们在其他组件中使用serviceproperty变量。在app.component.ts中,我们访问变量的方式如下:

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 4 Project!';
   todaydate;
   componentproperty;
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
      console.log(this.myservice.serviceproperty);
      this.myservice.serviceproperty = "component created"; // value is changed.
      this.componentproperty = this.myservice.serviceproperty;
   }
}

我们现在将获取变量并在console.log中使用它。在下一行,我们将变量的值更改为"component created"。我们将在new-cmp.component.ts中执行相同的操作。

import { Component, OnInit } from '@angular/core';
import { MyserviceService } from './../myservice.service';
@Component({
   selector: 'app-new-cmp',
   templateUrl: './new-cmp.component.html',
   styleUrls: ['./new-cmp.component.css']
})
export class NewCmpComponent implements OnInit {
   todaydate;
   newcomponentproperty;
   newcomponent = "Entered in newcomponent";
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
      this.newcomponentproperty = this.myservice.serviceproperty;
   }
}

在上面的组件中,我们没有更改任何内容,而是直接将属性分配给组件属性。

现在,当您在浏览器中执行它时,服务属性将被更改,因为它的值在app.component.ts中被更改,并且new-cmp.component.ts将显示相同的内容。

在更改之前,还要检查控制台中的值。

Console Output

Angular 6 - Http 服务

Http服务将帮助我们获取外部数据、向其发布数据等。我们需要导入http模块才能使用http服务。让我们考虑一个示例来了解如何使用http服务。

要开始使用http服务,我们需要在app.module.ts中导入模块,如下所示:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule,
      HttpModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

如果您看到突出显示的代码,我们已经从@angular/http导入HttpModule,并且它也添加到导入数组中。

现在让我们在app.component.ts中使用http服务。

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: Http) { }
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users").
      map((response) ⇒ response.json()).
      subscribe((data) ⇒ console.log(data))
   }
}

让我们理解上面突出显示的代码。我们需要导入http才能使用该服务,操作如下:

import { Http } from '@angular/http';

在类AppComponent中,创建了一个构造函数和类型为Http的私有变量http。要获取数据,我们需要使用http提供的get API,如下所示

this.http.get();

它将要获取的url作为参数,如代码所示。

我们将使用测试url - https://jsonplaceholder.typicode.com/users来获取json数据。在获取的url数据上执行两个操作:map和subscribe。Map方法有助于将数据转换为json格式。要使用map,我们需要导入它,如下所示:

import {map} from 'rxjs/operators';

Map完成后,subscribe将在控制台中记录输出,如浏览器中所示:

Console Output Of Map

如果您看到,json对象显示在控制台中。这些对象也可以在浏览器中显示。

要使对象在浏览器中显示,请在app.component.htmlapp.component.ts中更新代码,如下所示:

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { map} from 'rxjs/operators';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: Http) { }
   httpdata;
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users")
      .pipe(map((response) => response.json()))
      .subscribe((data) => this.displaydata(data));     
   }
   displaydata(data) {this.httpdata = data;}
}

app.component.ts中,使用subscribe方法,我们将调用display data方法并将获取的数据作为参数传递给它。

在display data方法中,我们将数据存储在一个名为httpdata的变量中。使用for循环在浏览器中显示此httpdata变量中的数据,这在app.component.html文件中完成。

<ul *ngFor = "let data of httpdata">
   <li>Name : {{data.name}} Address: {{data.address.city}}</li>
</ul>

json对象如下所示:

{
   "id": 1,
   "name": "Leanne Graham",
   "username": "Bret",
   "email": "Sincere@april.biz",
   
   "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
         "lat": "-37.3159",
         "lng": "81.1496"
      }
   },
   
   "phone": "1-770-736-8031 x56442",
   "website": "hildegard.org",
   "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
   }
}

该对象具有id、name、username、email和address等属性,address内部包含street、city等,以及与phone、website和company相关的其他详细信息。使用for循环,我们将在浏览器中显示name和city详细信息,如app.component.html文件中所示。

浏览器中显示的方式如下:

Using For-Loop Name City Details

现在让我们添加搜索参数,它将根据特定数据进行过滤。我们需要根据传递的搜索参数获取数据。

以下是app.component.htmlapp.component.ts文件中所做的更改:

app.component.ts

import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { map} from 'rxjs/operators';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: Http) { }
   httpdata;
   name;
   searchparam = 2;
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users?id="+this.searchparam)
      .pipe(map((response) => response.json()))
      .subscribe((data) => this.displaydata(data));     
   }
   displaydata(data) {this.httpdata = data;}
}

对于get api,我们将添加搜索参数id = this.searchparam。searchparam等于2。我们需要json文件中id = 2的详细信息。

浏览器显示方式如下:

Ervin Howell

我们在浏览器中控制台输出了从http接收到的数据。它也在浏览器控制台中显示。浏览器中显示了json中id = 2的name。

Angular 6 - Http 客户端

HttpClient是在Angular 6中引入的,它将帮助我们获取外部数据、向其发布数据等。我们需要导入http模块才能使用http服务。让我们考虑一个示例来了解如何使用http服务。

要开始使用http服务,我们需要在app.module.ts中导入模块,如下所示:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule,
      HttpClientModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

如果您看到突出显示的代码,我们已经从@angular/common/http导入HttpClientModule,并且它也添加到导入数组中。

现在让我们在app.component.ts中使用http客户端。

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: HttpClient) { }
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users").
      subscribe((data) ⇒ console.log(data))
   }
}

让我们理解上面突出显示的代码。我们需要导入http才能使用该服务,操作如下:

import { HttpClient } from '@angular/common/http';

在类AppComponent中,创建了一个构造函数和类型为Http的私有变量http。要获取数据,我们需要使用http提供的get API,如下所示

this.http.get();

它将要获取的url作为参数,如代码所示。

我们将使用测试网址 − https://jsonplaceholder.typicode.com/users 来获取 JSON 数据。订阅将在控制台中记录输出,如浏览器中所示 −

Console Output Of Map

如果您看到,json对象显示在控制台中。这些对象也可以在浏览器中显示。

要使对象在浏览器中显示,请在app.component.htmlapp.component.ts中更新代码,如下所示:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: HttpClient) { }
   httpdata;
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users")
      .subscribe((data) => this.displaydata(data));     
   }
   displaydata(data) {this.httpdata = data;}
}

app.component.ts中,使用subscribe方法,我们将调用display data方法并将获取的数据作为参数传递给它。

在display data方法中,我们将数据存储在一个名为httpdata的变量中。使用for循环在浏览器中显示此httpdata变量中的数据,这在app.component.html文件中完成。

<ul *ngFor = "let data of httpdata">
   <li>Name : {{data.name}} Address: {{data.address.city}}</li>
</ul>

json对象如下所示:

{
   "id": 1,
   "name": "Leanne Graham",
   "username": "Bret",
   "email": "Sincere@april.biz",
   
   "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
         "lat": "-37.3159",
         "lng": "81.1496"
      }
   },
   
   "phone": "1-770-736-8031 x56442",
   "website": "hildegard.org",
   "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
   }
}

该对象具有id、name、username、email和address等属性,address内部包含street、city等,以及与phone、website和company相关的其他详细信息。使用for循环,我们将在浏览器中显示name和city详细信息,如app.component.html文件中所示。

浏览器中显示的方式如下:

Using For-Loop Name City Details

现在让我们添加搜索参数,它将根据特定数据进行过滤。我们需要根据传递的搜索参数获取数据。

以下是app.component.htmlapp.component.ts文件中所做的更改:

app.component.ts

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   constructor(private http: HttpClient) { }
   httpdata;
   name;
   searchparam = 2;
   ngOnInit() {
      this.http.get("http://jsonplaceholder.typicode.com/users?id="+this.searchparam)
      .subscribe((data) => this.displaydata(data));     
   }
   displaydata(data) {this.httpdata = data;}
}

对于get api,我们将添加搜索参数id = this.searchparam。searchparam等于2。我们需要json文件中id = 2的详细信息。

浏览器显示方式如下:

Ervin Howell

我们在浏览器中控制台输出了从http接收到的数据。它也在浏览器控制台中显示。浏览器中显示了json中id = 2的name。

Angular 6 - 表单

在本章中,我们将了解如何在 Angular 6 中使用表单。我们将讨论两种处理表单的方式 - 模板驱动表单和模型驱动表单。

模板驱动表单

对于模板驱动表单,大部分工作都在模板中完成;而对于模型驱动表单,大部分工作都在组件类中完成。

现在让我们考虑在模板驱动表单上工作。我们将创建一个简单的登录表单,并在表单中添加电子邮件 ID、密码和提交按钮。首先,我们需要从@angular/core导入 FormsModule,这在app.module.ts中完成,如下所示 −

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule} from '@angular/router';
import { HttpModule } from '@angular/http';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { MyserviceService } from './myservice.service';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule,
      HttpModule,
      FormsModule,
      RouterModule.forRoot([
         {path: 'new-cmp',component: NewCmpComponent}
      ])
   ],
   providers: [MyserviceService],
   bootstrap: [AppComponent]
})
export class AppModule { }

因此,在app.module.ts中,我们导入了 FormsModule,并在 imports 数组中添加了它,如突出显示的代码所示。

现在让我们在app.component.html文件中创建表单。

<form #userlogin = "ngForm" (ngSubmit) = "onClickSubmit(userlogin.value)" >
   <input type = "text" name = "emailid" placeholder = "emailid" ngModel>
   <br/>
   <input type = "password" name = "passwd" placeholder = "passwd" ngModel>
   <br/>
   <input type = "submit" value = "submit">
</form>

我们创建了一个简单的表单,其中包含具有电子邮件 ID、密码和提交按钮的输入标签。我们已为其分配了类型、名称和占位符。

在模板驱动表单中,我们需要通过添加ngModel指令和name属性来创建模型表单控件。因此,在任何我们希望 Angular 从表单中访问我们的数据的地方,都向该标签添加 ngModel,如上所示。现在,如果我们必须读取 emailid 和 passwd,我们需要在它们上面添加 ngModel。

如果看到,我们还在#userlogin中添加了 ngForm。ngForm指令需要添加到我们创建的表单模板中。我们还添加了函数onClickSubmit并将其分配给userlogin.value

现在让我们在app.component.ts中创建函数并获取在表单中输入的值。

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate;
   componentproperty;
   constructor(private myservice: MyserviceService) { }
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
   }
   onClickSubmit(data) {
      alert("Entered Email id : " + data.emailid);
   }
}

在上面的app.component.ts文件中,我们定义了函数 onClickSubmit。当单击表单提交按钮时,控制权将转到上述函数。

浏览器显示方式如下:

onClickSubmit Login

表单如下所示。让我们在其中输入数据,并在提交函数中,电子邮件 ID 已经输入。

Email Enterd Login

电子邮件 ID 显示在底部,如上图所示。

模型驱动表单

在模型驱动表单中,我们需要从 @angular/forms 导入 ReactiveFormsModule,并在 imports 数组中使用它。

app.module.ts中会有一些更改。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule} from '@angular/router';
import { HttpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { MyserviceService } from './myservice.service';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective
   ],
   imports: [
      BrowserModule,
      HttpModule,
      ReactiveFormsModule,
      RouterModule.forRoot([
         {
            path: 'new-cmp',
            component: NewCmpComponent
         }
      ])
   ],
   providers: [MyserviceService],
   bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts中,我们需要为模型驱动表单导入一些模块。例如,import { FormGroup, FormControl } from '@angular/forms'

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate;
   componentproperty;
   emailid;
   formdata;
   constructor(private myservice: MyserviceService) { }
   ngOnInit() {
      this.todaydate = this.myservice.showTodayDate();
      this.formdata = new FormGroup({
         emailid: new FormControl("angular@gmail.com"),
         passwd: new FormControl("abcd1234")
      });
   }
   onClickSubmit(data) {this.emailid = data.emailid;}
}

变量 formdata 在类的开头初始化,并如上所示初始化为 FormGroup。变量 emailid 和 passwd 初始化为默认值,以便在表单中显示。如果需要,可以将其保留为空。

表单 UI 中将显示这些值。

Form UI

我们使用 formdata 初始化表单值;我们需要在表单 UI app.component.html中使用它。

<div>
   <form [formGroup] = "formdata" (ngSubmit) = "onClickSubmit(formdata.value)" >
      <input type = "text" class = "fortextbox" name = "emailid" placeholder = "emailid" 
         formControlName="emailid">
      <br/>
      
      <input type = "password" class = "fortextbox" name="passwd" 
         placeholder = "passwd" formControlName = "passwd">
      <br/>
      
      <input type = "submit" class = "forsubmit" value = "Log In">
   </form>
</div>
<p>
   Email entered is : {{emailid}}
</p>

在 .html 文件中,我们使用了方括号中的 formGroup 用于表单;例如,[formGroup]="formdata"。提交时,调用函数onClickSubmit并传递formdata.value

使用了输入标签formControlName。它被赋予了一个我们在app.component.ts文件中使用的值。

单击提交后,控制权将传递给函数onClickSubmit,该函数在app.component.ts文件中定义。

Screenshot onClickSubmit Event

单击登录后,将显示该值,如上图所示。

表单验证

现在让我们讨论使用模型驱动表单进行表单验证。可以使用内置的表单验证,也可以使用自定义验证方法。我们将在表单中使用这两种方法。我们将继续使用我们在前面章节中创建的相同示例。在 Angular 4 中,我们需要从@angular/forms导入 Validators,如下所示 −

import { FormGroup, FormControl, Validators} from '@angular/forms'

Angular 具有内置的验证器,例如必填字段、最小长度、最大长度模式。这些可以通过 Validators 模块访问。

只需添加验证器或所需验证器的数组即可告诉 Angular 特定字段是否为必填字段。

现在让我们在一个输入文本框(即电子邮件 ID)上尝试相同操作。对于电子邮件 ID,我们添加了以下验证参数 −

  • 必填
  • 模式匹配

这是app.component.ts中代码如何进行验证的。

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators} from '@angular/forms';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate;
   componentproperty;
   emailid;
   formdata;
   ngOnInit() {
      this.formdata = new FormGroup({
         emailid: new FormControl("", Validators.compose([
            Validators.required,
            Validators.pattern("[^ @]*@[^ @]*")
         ])),
         passwd: new FormControl("")
      });
   }
   onClickSubmit(data) {this.emailid = data.emailid;}
}

Validators.compose中,可以添加要在输入字段上验证的事项列表。现在,我们添加了必填模式匹配参数,以便仅接受有效的电子邮件。

app.component.html中,如果任何表单输入无效,则提交按钮将被禁用。操作方法如下 −

<div>
   <form [formGroup] = "formdata" (ngSubmit) = "onClickSubmit(formdata.value)" >
      <input type = "text" class = "fortextbox" name = "emailid" placeholder = "emailid" 
         formControlName = "emailid">
      <br/>
      <input type = "password" class = "fortextbox" name = "passwd" 
         placeholder = "passwd" formControlName = "passwd">
      <br/>
      <input type = "submit" [disabled] = "!formdata.valid" class = "forsubmit" 
         value = "Log In">
   </form>
</div>
<p>
   Email entered is : {{emailid}}
</p>

对于提交按钮,我们在方括号中添加了 disabled,该值设置为 - !formdata.valid。因此,如果 formdata.valid 无效,则按钮将保持禁用状态,用户将无法提交它。

让我们看看它在浏览器中的工作方式 −

!formdata.valid Event Output

在上述情况下,输入的电子邮件 ID 无效,因此登录按钮被禁用。现在让我们尝试输入有效的电子邮件 ID 并查看区别。

Disabled Login Button

现在,输入的电子邮件 ID 有效。因此,我们可以看到登录按钮已启用,用户将能够提交它。这样,输入的电子邮件 ID 将显示在底部。

现在让我们尝试使用相同的表单进行自定义验证。对于自定义验证,我们可以定义自己的自定义函数并在其中添加所需详细信息。现在我们将看到一个示例。

import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators} from '@angular/forms';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 6 Project!';
   todaydate;
   componentproperty;
   emailid;
   formdata;
   ngOnInit() {
      this.formdata = new FormGroup({
         emailid: new FormControl("", Validators.compose([
            Validators.required,
            Validators.pattern("[^ @]*@[^ @]*")
         ])),
         passwd: new FormControl("", this.passwordvalidation)
      });
   }
   passwordvalidation(formcontrol) {
      if (formcontrol.value.length < 5) {
         return {"passwd" : true};
      }
   }
   onClickSubmit(data) {this.emailid = data.emailid;}
}

在上面的示例中,我们创建了一个函数password validation,并在表单控件中使用了它 - passwd: new FormControl("", this.passwordvalidation)

在我们创建的函数中,我们将检查输入字符的长度是否合适。如果字符少于五个,它将返回 passwd 为 true,如上所示 - return {"passwd" : true};。如果字符多于五个,则将其视为有效,并且登录将被启用。

现在让我们看看它在浏览器中的显示方式 −

Three Characters Entered In Password

我们在密码中只输入了三个字符,登录被禁用。要启用登录,我们需要超过五个字符。现在让我们输入有效长度的字符并检查。

Valid ID Password Enables Login

登录已启用,因为电子邮件 ID 和密码均有效。登录后,电子邮件将显示在底部。

Angular 6 - 动画

动画增加了 HTML 元素之间的许多交互。Angular 2 中也提供了动画。与 Angular 6 的区别在于,动画不再是@angular/core库的一部分,而是一个需要在app.module.ts中导入的单独包。

首先,我们需要导入库,如下所示 −

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

BrowserAnimationsModule需要添加到app.module.ts中的 import 数组中,如下所示 −

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html中,我们添加了要进行动画处理的 HTML 元素。

<div>
   <button (click) = "animate()">Click Me</button>
   <div [@myanimation] = "state" class = "rotate">
      <img src = "assets/images/img.png" width = "100" height = "100">
   </div>
</div>

对于主 div,我们添加了一个按钮和一个包含图像的 div。有一个点击事件,为此调用 animate 函数。并且对于 div,添加了@myanimation指令并将其值设置为 state。

现在让我们看看定义动画的app.component.ts

import { Component } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css'],
   styles:[`
      div{
         margin: 0 auto;
         text-align: center;
         width:200px;
      }
      .rotate{
         width:100px;
         height:100px;
         border:solid 1px red;
      }
   `],
   animations: [
      trigger('myanimation',[
         state('smaller',style({
            transform : 'translateY(100px)'
         })),
         state('larger',style({
            transform : 'translateY(0px)'
         })),
         transition('smaller <=> larger',animate('300ms ease-in'))
      ])
   ]
})
export class AppComponent {
   state: string = "smaller";
   animate() {
      this.state= this.state == 'larger' ? 'smaller' : 'larger';
   }
}

我们必须导入要在 .ts 文件中使用的动画函数,如上所示。

import { trigger, state, style, transition, animate } from '@angular/animations';

在这里,我们从 @angular/animations 导入了 trigger、state、style、transition 和 animate。

现在,我们将 animations 属性添加到 @Component() 装饰器中 −

animations: [
   trigger('myanimation',[
      state('smaller',style({
         transform : 'translateY(100px)'
      })),
      state('larger',style({
         transform : 'translateY(0px)'
      })),
      transition('smaller <=> larger',animate('300ms ease-in'))
   ])
]

Trigger 定义动画的开始。它的第一个参数是要赋予 HTML 标签的动画名称,该动画需要应用于该标签。第二个参数是我们导入的函数 - state、transition 等。

state函数包含动画步骤,元素将在这些步骤之间进行转换。现在我们定义了两个状态,smaller 和 larger。对于 smaller 状态,我们给出了样式transform:translateY(100px)transform:translateY(100px)

Transition 函数向 HTML 元素添加动画。第一个参数获取状态,即开始和结束;第二个参数接受 animate 函数。animate 函数允许定义转换的长度、延迟和缓动。

现在让我们查看 .html 文件以了解 transition 函数的工作原理

<div>
   <button (click) = "animate()">Click Me</button>
   <div [@myanimation] = "state" class="rotate">
      <img src = "assets/images/img.png" width = "100" height = "100">
   </div>
</div>

@component指令中添加了一个 style 属性,它将 div 居中对齐。让我们考虑以下示例以了解相同内容 −

styles:[`
   div{
      margin: 0 auto;
      text-align: center;
      width:200px;
   }
   .rotate{
      width:100px;
      height:100px;
      border:solid 1px red;
   }
`],

在这里,使用特殊字符 [``] 向 HTML 元素添加样式(如果有)。对于 div,我们给出了在 app.component.ts 文件中定义的动画名称。

单击按钮时,它会调用在 app.component.ts 文件中定义的 animate 函数,如下所示 −

export class AppComponent {
   state: string = "smaller";
   animate() {
      this.state= this.state == ‘larger’? 'smaller' : 'larger';
   }
}

定义了 state 变量,并将其默认值设置为 smaller。animate 函数在单击时更改状态。如果状态为 larger,它将转换为 smaller;如果为 smaller,它将转换为 larger。

浏览器 (https://:4200/) 中的输出将如下所示 −

Click Me Button

单击Click Me按钮后,图像的位置将发生变化,如下面的屏幕截图所示 −

Click Me Button Image Position Changed

transform 函数应用于y方向,当单击 Click Me 按钮时,它会从 0 更改为 100px。图像存储在assets/images文件夹中。

Angular 6 - 材料

Materials为您的项目提供了许多内置模块。自动完成、日期选择器、滑块、菜单、网格和工具栏等功能可用于 Angular 6 中的材料。

要使用材料,我们需要导入包。Angular 2 也具有所有上述功能,但它们作为 @angular/core 模块的一部分提供。Angular 6 推出了一个单独的模块@angular/materials.。这有助于用户导入所需的材料。

要开始使用材料,需要安装两个包 - materials 和 cdk。Material 组件依赖于动画模块以获得高级功能,因此需要为此使用动画包,即 @angular/animations。该包已在上一章中更新。

npm install --save @angular/material @angular/cdk

现在让我们查看 package.json。已安装@angular/material@angular/cdk

{
  "name": "angular6-app",
  "version": "0.0.0",
  "scripts": {
      "ng": "ng",
      "start": "ng serve",
      "build": "ng build",
      "test": "ng test",
      "lint": "ng lint",
      "e2e": "ng e2e"
   },
   "private": true, "dependencies": {
      "@angular/animations": "^6.1.0",
      "@angular/cdk": "^6.4.7",
      "@angular/common": "^6.1.0",
      "@angular/compiler": "^6.1.0",
      "@angular/core": "^6.1.0",
      "@angular/forms": "^6.1.0",
      "@angular/http": "^6.1.0",
      "@angular/material": "^6.4.7",
      "@angular/platform-browser": "^6.1.0",
      "@angular/platform-browser-dynamic": "^6.1.0",
      "@angular/router": "^6.1.0",
      "core-js": "^2.5.4",
      "rxjs": "^6.0.0",
      "zone.js": "~0.8.26"
   },
   "devDependencies": {
      "@angular-devkit/build-angular": "~0.7.0",
      "@angular/cli": "~6.1.3",
      "@angular/compiler-cli": "^6.1.0",
      "@angular/language-service": "^6.1.0",
      "@types/jasmine": "~2.8.6",
      "@types/jasminewd2": "~2.0.3",
      "@types/node": "~8.9.4",
      "codelyzer": "~4.2.1",
      "jasmine-core": "~2.99.1",
      "jasmine-spec-reporter": "~4.2.1",
      "karma": "~1.7.1",
      "karma-chrome-launcher": "~2.2.0",
      "karma-coverage-istanbul-reporter": "~2.0.0",
      "karma-jasmine": "~1.1.1",
      "karma-jasmine-html-reporter": "^0.2.2",
      "protractor": "~5.3.0",
      "ts-node": "~5.0.1",
      "tslint": "~5.9.1",
      "typescript": "~2.7.2"
   }
}

我们突出显示了安装以使用材料的包。

现在我们将在父模块 - app.module.ts中导入模块,如下所示。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule, MatMenuModule, MatSidenavModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule,
      MatButtonModule,
      MatMenuModule,
      FormsModule,
      MatSidenavModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

在上述文件中,我们从 @angular/materials 导入了以下模块。

import { MatButtonModule, MatMenuModule, MatSidenavModule } from '@angular/material';

并在 imports 数组中使用了它,如下所示 −

imports: [
   BrowserModule,
   BrowserAnimationsModule,
   MatButtonModule,
   MatMenuModule,
   FormsModule,
   MatSidenavModule
]

app.component.ts如下所示 −

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   myData: Array<any>;
   constructor() {}
}

现在让我们在styles.css中添加 material-css 支持。

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

现在让我们在app.component.html中添加材料。

<button mat-button [matMenuTriggerFor] = "menu">Menu</button>
<mat-menu #menu = "matMenu">
   <button mat-menu-item>
      File
   </button>
   <button mat-menu-item>
      Save As
   </button>
</mat-menu>
<mat-sidenav-container class = "example-container">
   <mat-sidenav #sidenav class = "example-sidenav">
      Angular 6
   </mat-sidenav>
   <div class = "example-sidenav-content">
      <button type = "button" mat-button  (click) = "sidenav.open()">
         Open sidenav
      </button>
   </div>
</mat-sidenav-container>

在上述文件中,我们添加了 Menu 和 SideNav。

菜单

要添加菜单,使用<mat-menu></mat-menu>fileSave As项添加到mat-menu下按钮。添加了一个主按钮Menu。通过使用[matMenuTriggerFor]="menu"将同一个的引用赋予<mat-menu>,并在# in <mat-menu>中使用菜单。

侧边栏

要添加侧边栏,我们需要<mat-sidenav-container></mat-sidenav-container><mat-sidenav></mat-sidenav>作为子元素添加到容器中。添加了另一个 div,它通过使用(click)="sidenav.open()"触发侧边栏。以下是菜单和侧边栏在浏览器中的显示 −

Open Sidenav Menu

单击opensidenav后,它将显示侧边栏,如下所示 −

Open Sidenav Side Bar

单击菜单后,您将获得两个项目FileSave As,如下所示 −

Click Open Sidenav Shows Item

现在让我们使用 Material 添加一个日期选择器。要添加日期选择器,我们需要导入显示日期选择器所需的模块。

app.module.ts中,我们导入了以下模块,如下所示,用于日期选择器。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatDatepickerModule, MatInputModule, MatNativeDateModule } from '@angular/material';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule,
      BrowserAnimationsModule,
      FormsModule,
      MatDatepickerModule,
      MatInputModule,
      MatNativeDateModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule { }

这里,我们导入了诸如MatDatepickerModule、MatInputModuleMatNativeDateModule之类的模块。

现在,app.component.ts如下所示:

import { Component } from '@angular/core';
@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   myData: Array<any>;
   constructor() {}
}

app.component.html如下所示:

<mat-form-field>
   <input matInput [matDatepicker] = "picker" placeholder = "Choose a date">
   <mat-datepicker-toggle matSuffix [for] = "picker"></mat-datepicker-toggle>
   <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

这就是日期选择器在浏览器中显示的方式。

Datepicker Is Displayed

Angular 6 - CLI

Angular CLI 使任何 Angular 项目的启动变得容易。Angular CLI 带有命令,可以帮助我们非常快速地创建和启动项目。现在让我们了解一下可用于创建项目、组件和服务、更改端口等的命令。

要使用 Angular CLI,我们需要在系统上安装它。让我们使用以下命令来实现:

npm install -g @angular/cli

要创建一个新项目,我们可以在命令行中运行以下命令,然后项目将被创建。

ng new PROJECT-NAME
cd PROJECT-NAME
ng serve //

ng serve // 将编译,您可以在浏览器中看到项目的输出:

https://:4200/

4200 是创建新项目时使用的默认端口。您可以使用以下命令更改端口:

ng serve --host 0.0.0.0 --port 4201

下表列出了使用 Angular 4 项目时所需的一些重要命令。

组件 ng g component new-component
指令 ng g directive new-directive
管道 ng g pipe new-pipe
服务 ng g service new-service
模块 ng g module my-module

每当创建新的模块、组件或服务时,其引用都会在父模块app.module.ts中更新。

广告

© . All rights reserved.