Angular

简介

AngularJS 是一个 JavaScript 框架。它可通过

AngularJS 通过 指令 扩展了 HTML,且通过 表达式 绑定数据到 HTML。

AngularJS 扩展了 HTML

AngularJS 通过 ng-directives 扩展了 HTML。

ng-app 指令定义一个 AngularJS 应用程序。

ng-model 指令把元素值(比如输入域的值)绑定到应用程序。

ng-bind 指令把应用程序数据绑定到 HTML 视图。

Angular提倡的文件命名方式

组件名称.component.ts

组件的HTML模板命名为: 组件名称.component.html

组件的样式文件命名为: 组件名称.component.css

在使用angular前,需要先配置环境

  1. node.js

  2. 安装完node后可以将npm资源库设置成国内淘宝镜像,下载cnpm

    npm config set registry https://registry.npm.taobao.org

    npm install -g cnpm --registry=https://registry.npm.taobao.org

  3. 安装CLI

    3.1:在安装了cnpm的目录下打开命令行

    3.2:输入cnpm install -g @angular/cli

    3.3:通过ng v命令可查看是否安装成功

  4. 安装TypeScript

    4.1:cnpm install -g typescript

    4.2:tsc -v可查看是否安装成功

  5. 安装saas

    5.1:npm install node-sass --registry=http://registry.npm.taobao.org

    5.2:安装saas中间会报几次错误,遇到错误重新安装即可

搭建项目

1.使用命令行创建

1.1cnpm下创建项目。(做Demo时候可以使用)

​ 切换到要创建项目的目录,命令行输入:ng new frontend

2.使用cnpm安装Primeng

2.1 进入项目根目录
2.2 cnpm install primeng --save

2.3安装第三方字体awesome:

​ cnpm install font-awesome

2.4安装Augular4+动画

​ cnpm install @angular/animations --save

2.5安装jquery

​ npm install jquery --save(遇到错误重复安装即可)

​ npm install @types/jquery --save

2.6命令行输入ng serve即可通过localhost:4200访问欢迎界面

  • @Component:这是一个 Decorator(装饰器),其作用类似于 Java 里面的注解。Decorator 这个语言特性目前(2017-10)处于 Stage 2(草稿)状态,还不是 ECMA 的正式规范。
  • selector:组件的标签名,外部使用者可以这样来使用这个组件:。默认情况下,ng 命令生成出来的组件都会带上一个 app 前缀,如果你不喜欢,可以在 angular-cli.json 里面修改 prefix 配置项,设置为空字符串将会不带任何前缀。
  • templateUrl:引用外部的 HTML 模板。如果你想直接编写内联模板,可以使用 template,支持 ES6 引入的“模板字符串”写法。
  • styleUrls:引用外部 CSS 样式文件,这是一个数组,也就意味着可以引用多份 CSS 文件。
  • export class AppComponent:这是 ES6 里面引入的模块和 class 定义方式

何为“轻逻辑”?

简而言之,所谓“轻逻辑”就是说,你不能在模板里面编写非常复杂的 JavaScript 表达式。比如,Angular 的模板语法就有规定:

  • 你不能在模板里面 new 对象
  • 不能使用=、+=、-=这类的表达式
  • 不能用++、–运算符
  • 不能使用位运算符

第一个组件

命令行窗口输入 ng generate component login --inline-template --inline-style

参数generate用来生成文件,参数component说明要生成一个组件,login是组件名称,后面的两个参数是告诉angular-cli:生成组件时,请把组件的HTML模板和CSS样式和组件放在同一个文件中(其实分开文件更清晰。)

可以把上面的命令改写成 ng g c login -it -is

angular-cli为我们在\src\app目录下生成了一个新文件夹login,在login目录下生成了2个文件

@Component修饰配置中的 selector: 'app-login',意味着可以在其他组件的template中使用 <app-login></app-login> 来引用这个组件。

什么是模块?

简单来说模块就是提供相对独立功能的功能块,每块聚焦于一个特定业务领域。Angular内建的很多库是以模块形式提供的,比如FormsModule封装了表单处理,HttpModule封装了Http的处理等等。每个Angular应用至少有一个模块类 —— 根模块,我们将通过引导根模块来启动应用。按照约定,根模块的类名叫做AppModule,被放在 app.module.ts 文件中。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';@NgModule({ //@NgModule装饰器用来为模块定义元数据。declarations: [AppComponent,LoginComponent],imports: [BrowserModule,AppRoutingModule,],providers: [],bootstrap: [AppComponent]
})
export class AppModule { }

Angular的服务与依赖注入

创建一个 AuthService , 在 src\app 下建立一个 core 的子文件夹( src/app/core ),命令行中输入 ng g s core/auth ( s这里是service的缩写,core/auth 是说在 core 的目录下建立 auth 服务相关文件

service 添加一个方法,为这个方法指定了返回类型和参数类型。这就是 TypeScript 的好处,有了类型约束,在别处调用这个方法时,如果给出的参数类型或返回类型不正确,IDE就可以直接告诉你错了。

import { Injectable } from '@angular/core';@Injectable({providedIn: 'root'
})
export class AuthService {constructor() { }loginWithCredentials(username: string, password: string): boolean {if(username === 'wangpeng')return true;return false;}
}

这个service虽然被创建了,但仍无法在Component中使用,可以直接在Component中import这个服务,但这样耦合性比较高,Angular提供了依赖性注入的方法

如何使用DI

在组件的修饰器中配置AuthService,然后在组件的构造函数中使用参数进行依赖注入。

import { Component, Inject, OnInit } from '@angular/core';
import { AuthService } from '../core/auth.service';@Component({selector: 'app-login',template: `<div><input #usernameRef type="text"><input #passwordRef type="password"><button (click)="onClick(usernameRef.value, passwordRef.value)">Login</button></div>`,styles: [],providers:[AuthService]//在providers中配置AuthService
})
export class LoginComponent implements OnInit {//在构造函数中将AuthService示例注入到成员变量service中//而且我们不需要显式声明成员变量service了constructor(private service:AuthService) { }ngOnInit(): void {}onClick(username:string, password:string) {console.log('auth result is: ' + this.service.loginWithCredentials(username, password));}
}

双向数据绑定

angular 提供了一个双向数据绑定的机制。这个机制是这样的,在组件中提供成员数据变量,然后在模板中引用这个数据变量。

在class中声明变量:

  username = "";password = "";

方法改造,去掉onClick中的参数,改为this.*调用

onClick() {console.log('auth result is: ' + this.service.loginWithCredentials(this.username, this.password));}

模板:

    <div><input type="text"[(ngModel)]="username"/><input type="password"[(ngModel)]="password"/><button (click)="onClick()">Login</button></div>

[(ngModel)]="username"

[]的作用:把等号后面当成表达式来解析而不是当成字符串,如果去掉方括号等于将 ngModel 赋值成 username 这个字符串。方括号的含义是单向绑定,即在组件中给 model 赋的值会设置到 HTML 的 input 控件中。 [()] 是双向绑定的意思,即HTML对应控件的状态的改变会反射设置到组件的 model 中。

ngModel 是 FormModule 中提供的指令,负责从Domain Model(这里就是 username 或 password )中创建一个 FormControl 的实例,并将这个实例和表单的控件绑定起来。

表单数据的验证

<div><input type="text"[(ngModel)]="username"#usernameRef="ngModel"requiredminlength="3"/>{{ usernameRef.errors | json }}<div *ngIf="usernameRef.errors?.required">this is required</div><div *ngIf="usernameRef.errors?.minlength">should be at least 3 charactors</div><input required type="password"[(ngModel)]="password"#passwordRef="ngModel"/><div *ngIf="passwordRef.errors?.required">this is required</div><button (click)="onClick()">Login</button></div

ngIf是一个Angular2的指令,是用于做条件判断的。*ngIf="usernameRef.errors?.required"的意思是当usernameRef.errors.requiredtrue时显示div标签。那么那个?是干嘛的呢?因为errors可能是个null,如果这个时候调用errorsrequired属性肯定会引发异常,那么?就是标明errors可能为空,在其为空时就不用调用后面的属性了。

<div><form #formRef="ngForm"><input type="text"name="username"//要指定name不然会报错[(ngModel)]="username"#usernameRef="ngModel"requiredminlength="3"/><div *ngIf="usernameRef.errors?.required">this is required</div><div *ngIf="usernameRef.errors?.minlength">should be at least 3 charactors</div><input type="password"name="password"[(ngModel)]="password"#passwordRef="ngModel"required/><div *ngIf="passwordRef.errors?.required">this is required</div><button (click)="onClick()">Login</button><button type="submit">Submit</button></form></div>

表单项过多时可以用HTML提供的fieldset标签来处理,<fieldset ngModelGroup="login"> 对于 fieldset 之内的数据都分组到了 login 对象中。

*ngFor 是一个 “结构型指令”。结构型指令会通过添加、删除和操纵它们的宿主元素等方式塑造或重塑 DOM 的结构。带有星号 * 的指令都是结构型指令。

Angular 模板语法的五个常用特性:

  • *ngFor
  • *ngIf
  • 插值 {{}}
  • 属性绑定 []
  • 事件绑定 ()

组件

组件在用户界面(也就是 UI)中定义了一些责任区,让你能复用这些 UI 功能集。你已经通过商品列表组件构建了一个。

组件包含三部分:

  • 一个组件类,它用来处理数据和功能。上一节,我们在组件类中定义了商品数据和 share() 方法,它们分别用来处理数据和功能。
  • 一个 HTML 模板,它决定了 UI。在上一节中,商品列表的 HTML 模板用来显示每个商品的名称、描述和 “Share” 按钮。
  • 组件专属的样式定义了外观和感觉。商品列表中还没有定义任何样式,那属于组件 CSS 负责。

  • app-root(橙色框)是应用的外壳。这是要加载的第一个组件,也是所有其它组件的父组件。你可以把它想象成一个基础页面。
  • app-top-bar(蓝色背景)是商店名称和结帐按钮。
  • app-product-list(紫色框)是你在上一节中修改过的商品列表。

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

定义一个带 @Input() 装饰器的 product 属性。@Input() 装饰器指出其属性值是从该组件的父组件商品列表组件中传入的。

import { Output, EventEmitter } from '@angular/core';

@Output() 装饰器,事件发射器 EventEmitter()

@Output() notify = new EventEmitter();notify 属性发生变化时发出事件。

父组件要接收子组件发出的事件

路由

Angular 路由器能让你在不同的视图中显示产品的详情,每个产品都有自己的 URL。当用户执行应用任务时,路由器可以从一个视图导航到另一个视图(但在同一个页面)。比如:

  • 在地址栏中输入一个 URL,导航到相应的页面。
  • 点击页面上的链接,导航到新页面。
  • 点击浏览器的后退和前进按钮,在浏览器的历史中前后导航
  1. 为商品详情生成一个新组件。把组件命名为 product-details

    提示:在文件列表框中,右键单击 app 文件夹,选择 Angular GeneratorComponent

  2. app.module.ts 中,添加一个商品详情路由,该路由的 pathproducts/:productIdcomponentProductDetailsComponent

    路由会将一个或多个 URL 路径与一个组件关联起来。

  3. 该指令配置组件的模板,以定义用户如何导航到路由或 URL。当用户点击商品名称时,应用就会显示那个商品的详情。

    1. 打开 product-list.component.html

    2. 修改 *ngFor 指令,在遍历列表的过程中把 products 数组中的每个索引赋值给 productId 变量。

    3. 修改商品名称的链接,使其包含 routerLink

  4. RouterLink 指令让路由器控制了一个链接元素。在这种情况下,路由或 URL 包含一个固定的区段( /products ),但其最后一个区段是变量,要插入当前商品的 id 属性。例如,id 为 1 的商品的 URL 类似于 https://getting-started-myfork.stackblitz.io/products/1

使用路由信息

  1. 打开 product-details.component.ts 文件

  2. 改用外部文件中的商品数据。

    1. @angular/router 包导入 ActivatedRoute,从 ../products 文件导入 products 数组。

    2. 定义 product 属性,并将 ActivatedRoute 作为参数添加到构造函数的括号中,以便把它注入到构造函数中。

      (ActivatedRoute 专门用于由 Angular 路由器加载的每个路由组件。它包含关于该路由,路由参数以及与该路由关联的其它数据的信息。)

  3. ngOnInit() 方法中订阅了路由参数,并且根据 productId 获取了该产品。

  4. 修改模板,在 *ngIf 中显示商品详情。

    currency 管道来把 product.price 从数字转换成货币字符串。管道给了你一种在 HTML 模板中转换数据的方式。

管理数据

  • 修改商品详情视图,让它包含一个 “Buy” 按钮,它会把当前商品添加到由 “购物车服务” 管理的商品列表中。
  • 添加一个购物车组件,它会显示购物车中的商品。
  • 添加一个配送组件,它会使用 Angular 的 HttpClient.json 文件中检索配送数据来取得购物车中这些商品的运费。

创建购物车服务

生成service文件,并在其中写入有关商品与购物车操作的函数,引入HttpClient包,注入构造函数中。

product-details.component.ts 中导入购物车服务,并在构造函数的参数中注入服务

添加购物车组件,在app.module.ts中添加路由:{ path: 'cart', component: CartComponent },

显示购物车商品

在购物车组件中注入购物车服务,将购物车服务中定义的方法写入

检索运费价格

服务器通常采用流的形式返回数据。 流是很有用的,因为它们可以很容易地转换返回的数据,也可以修改你请求数据的方式。 Angular 的 HTTP 客户端( HttpClient )是一种内置的方式,可以从外部 API 中获取数据,并以流的形式提供给你的应用。

要使用Angular的HTTP客户端,必须在app.module.ts中导入HttpClientModule

import { HttpClientModule } from '@angular/common/http';
@NgModule({imports: [BrowserModule,HttpClientModule,//要import进来ReactiveFormsModule,...省略],

新建组件Shipping来使用CartService

利用 async 管道修改配送组件的模板,以显示配送类型和价格;

async 管道从数据流中返回最新值,并在所属组件的生命期内持续返回。当 Angular 销毁该组件时,async 管道会自动停止。

<h3>Shipping Prices</h3><div class="shipping-item" *ngFor="let shipping of shippingCosts | async"><span>{{ shipping.type }}</span><span>{{ shipping.price | currency }}</span>
</div>

在购物车视图中添加一个到配送视图的链接

<p><a routerLink="/shipping">Shipping Prices</a>
</p>

Angular中的表单

Angular 中的表单建立在标准 HTML 表单功能之上,以帮助你创建自定义表单控件和轻松的验证体验。Angular 响应式表单有两个部分:组件中那些用于存储和管理表单的对象,以及表单在模板中的可视化

ReactiveFormsModule 中提供了 FormBuilder 服务,FormBuilder 服务为生成控件提供了方便的方法。需要导入并注入该服务,然后才能使用它。

  1. 在CartComponent类中,定义checkoutForm来存储表单模型

  2. checkoutForm 属性设置为一个包含 nameaddress 字段的表单模型。使用 FormBuildergroup() 方法来创建它,把该语句加入构造函数的花括号 {} 中间。

  3. 创建结账表单

    1. 使用 formGroup 属性绑定把 checkoutForm 绑定到模板中的 form 标签上

    2. form 标签上,使用 ngSubmit 事件绑定来监听表单提交,并使用 checkoutForm 值调用 onSubmit() 方法

    3. nameaddress 添加输入字段。使用 formControlName 属性绑定来把 checkoutForm 表单控件中的 nameaddress 绑定到它们的输入字段

      <form [formGroup]="checkoutForm" (ngSubmit)="onSubmit(checkoutForm.value)"><div><label for="name">Name</label><input id="name" type="text" formControlName="name"></div><div><label for="address">Address</label><input id="address" type="text" formControlName="address"></div><button class="button" type="submit">Purchase</button>
      </form>
      
  4. 最终效果:

Angular-官方文档学习-1相关推荐

  1. Angular官方文档学习-英雄之旅

    Angular教程-英雄之旅 本教程需要完成的工作: 使用 Angular 的内置指令来显示 / 隐藏元素,并显示英雄数据的列表. 创建 Angular 组件以显示英雄的详情,并显示一个英雄数组. 为 ...

  2. ZooKeeper官方文档学习笔记03-程序员指南03

    我的每一篇这种正经文章,都是我努力克制玩心的成果,我可太难了,和自己做斗争. ZooKeeper官方文档学习笔记04-程序员指南03 绑定 Java绑定 客户端配置参数 C绑定 陷阱: 常见问题及故障 ...

  3. ZooKeeper官方文档学习笔记01-zookeeper概述

    纠结了很久,我决定用官方文档学习 ZooKeeper概述 学习文档 学习计划 ZooKeeper:分布式应用程序的分布式协调服务 设计目标 数据模型和分层名称空间 节点和短命节点 有条件的更新和监视 ...

  4. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)

    接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...

  5. Spring Boot 官方文档学习(一)入门及使用

    Spring Boot 官方文档学习(一)入门及使用 个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问 ...

  6. R语言reshape2包-官方文档学习

    R语言reshape2包-官方文档学习 简介 核心函数 长数据与宽数据 宽数据 长数据 melt函数 meltarray meltdataframe meltdefault meltlist cast ...

  7. Spring Data Commons 官方文档学习

    Spring Data Commons 官方文档学习   -by LarryZeal Version 1.12.6.Release, 2017-07-27 为知笔记版本在这里,带格式. Table o ...

  8. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

  9. jsTree 组件官方文档学习

    jsTree 组件官方文档学习 什么是 jsTree 根据jsTree官网的解释:jsTree 是一个jquery 插件, 提供交互式树.它是完全免费的,开源的,并根据MIT许可进行分发.jsTree ...

  10. HarmonyOS(一) 快速开始学习鸿蒙开发,官方文档学习路线解析

    系列文章目录 HarmonyOS(一):快速开始学习鸿蒙开发,官方文档学习路线解析 HarmonyOS(二):应用开发环境搭建准备 HarmonyOS(三):创建你的第一个HelloWorld应用 文 ...

最新文章

  1. hdu-1003 or 最大子序列和(四种解题方法)
  2. 独家 | 建立软件的经济学分析框架,浅议开源软件的经济学特性(附图解)
  3. redhat6.5 配置使用centos的yum源
  4. HDU 2393 Higher Math
  5. Altium.Designer的学习视频 分享~~
  6. 白话Elasticsearch06- 深度探秘搜索技术之手动控制全文检索结果的精准度
  7. MySQL误操作后如何快速恢复数据
  8. mysql 导入 相对路径,MySQL数据库导出与导入及常见错误解决
  9. 四篇关于恶意软件对抗方面的paper要点
  10. 找到符合条件的索引_程序员写了多年CRUD,总结出数据库索引这几点值得注意...
  11. 【Keras】使用数据生成器(data generators)解决训练数据内存问题
  12. c语言程序设计辅导资料pdf,C语言程序设计辅导资料(修订版).pdf
  13. python贝叶斯估计库_tsbngen一个python库,可从任意动态贝叶斯网络生成时间序列数据...
  14. 搭建Hive远程模式初始化的时候报错Access denied for user ‘root‘@‘node1‘(using password:YES)
  15. 达梦单机数据库服务器磁盘空间占满问题
  16. LoRa网关的特点及应用
  17. java 清除文本框数据_Java 添加、读取、删除Excel文本框
  18. 电脑开不了机启动不了|开机黑屏只有光标再闪
  19. ps人物磨皮美容插件:Pro Retouch Panel(支持ps2021)
  20. 微信小程序(小程序的生命周期)

热门文章

  1. 直通转发(cut-through)和存储转发(store-and-forward)的区别
  2. vue壁纸网站源码 自适应手机端 自动采集360壁纸接口
  3. 前端实现微信公众号h5页面跳转小程序-成功案例
  4. 推断统计 | 学习笔记 (全)
  5. 食品科学与工程考研可以考计算机吗,食品科学与工程考研考哪些科目
  6. 深度学习完全攻略!(连载二十:你家有老鼠吗?手把手教你怎么用faster-rcnn找出老鼠)
  7. jquery插件chosen多选时排序问题
  8. chosen.jquery.js 、chosen-select 源码修改控制 chosen:updated 方法动态更新下拉框选项不更新搜索框值 ,chosen 实现远程搜索加载下拉选项
  9. 查看linux下文件是否存在,linux中怎么查看文件是否存在
  10. 为什么持续改进值得吗?