技术文章 | Technical articles

Web前端三大框架_angular.js 6.0(三)

一、Angular 6.0

1.1自定义指令

1.1.1 icktBind

为元素绑定该数据, 类似插值语法

// 引入服务

import { Directive, ElementRef } from '@angular/core';

@Directive({

selector: '[icktBind]',

// 注册变量

inputs: ['icktBind']

})

export class IcktBindDirective {

10  // 声明属性变量接收数据的类型

11  icktBind:string;

12  // 参数注入并存储服务

13  constructor(public el: ElementRef) { }

14  // 监听数据改变

15  ngOnChanges(e) {

16   console.log(e)

17   // 渲染内容

18   this.el.nativeElement.innerHTML = this.icktBind;

19  }

20 }

21 

 

1.1.2 icktClass

实现对元素的类的绑定,有三种用法

字符串,就是一组类

数组,每个成员代表一组类

对象,属性值为true存储该类

 

// 引入服务

import { Directive, ElementRef } from '@angular/core';

@Directive({

selector: '[icktClass]',

// 注册数据

inputs: ['icktClass']

})

export class IcktClassDirective {

10  // 声明类型

11  icktClass: any;

12  // 注入服务,存储服务

13    constructor(protected el: ElementRef) { }

14    // 监听数据的变化

15    ngOnChanges() {

16     // 定义添加的类字符串

17     let cls:string = '';

18     // 判断数据类型

19     if (typeof this.icktClass === 'string') {

20      // 直接存储字符串

21      cls = this.icktClass;

22     // 判断数组 instanceof, constructor, Array.isArray Object.prototype.toString.call,

23     } else if (Array.isArray(this.icktClass)) {

24      // 将组数转化成字符串

25      cls = this.icktClass.join(' ');

26     } else {

27      // 遍历对象

28      for (let key in this.icktClass) {

29       // this.icktClass[key]表示属性值

30       if (this.icktClass[key]) {

31        // 存储key

32        cls += ' ' + key;

33       }

34      }

35      // 删除第一个空格

36      cls = cls.slice(1);

37     }

38     // console.log(this.icktClass)

39     // 更新元素的类

40     this.el.nativeElement.className = cls;

41    }

42 

43 }

44 

 

1.2组件生命周期

为了说明组件创建,存在,销毁的过程,ng6为我们提供了组件的生命周期。

ng6中,组件也是指令,组件的生命周期同样适用于指令(极其相似的)

创建期

constructor   表示组件构造函数,该方法执行说明,组件已经开始被创建了

ngOnInit    组件开始初始化

ngAfterContentInit 组件的数据开始初始化

ngAfterViewInit  组件的视图开始初始化

存在期:当组件(指令)的数据发生改变的时候,会进入存在期

ngOnChanges   表示指令的数据已经发生改变(指令所特有的方法

参数就是改变数据的对象

currentValue 当前的值

previousValue 上一个值

firstChange 是否是第一次(发生在创建期)数据改变

ngDoCheck    组件检测数据是否发生改变

ngAfterContentChecked 组件的数据更新完毕

ngAfterViewChecked 组件的视图更新完毕

销毁期

ngOnDestory   组件即将被销毁

注意

1 当组件进入创建期的时候,创建期的方法和存在期的方法会交替执行

2 当组件进入存在期的时候,只会执行存在期的方法,不会执行创建期的方法

3 所有方法的作用域(this)都是组件时候对象

 

图片1.png 

// 引入服务

import { Directive, ElementRef } from '@angular/core';

@Directive({

selector: '[icktBind]',

// 注册变量

inputs: ['icktBind']

})

export class IcktBindDirective {

10  // 声明属性变量接收数据的类型

11  icktBind:string;

12  // 组件构造函数

13  constructor() {

14   console.log(111, 'constructor', this, arguments)

15  }

16  // 组件开始初始化

17  ngOnInit() {

18   console.log(222, 'ngOnInit', this, arguments)

19  }

20  // 开始更新数据

21  ngAfterContentInit() {

22   console.log(333, 'ngAfterContentInit', this, arguments)

23  }

24  // 开始更新视图

25  ngAfterViewInit() {

26   console.log(444, 'ngAfterViewInit', this, arguments)

27  }

28  // 存在期

29  // 数据开始变化, 指令所特有的方法

30  ngOnChanges() {

31   console.log(1, 'ngOnChanges', this, arguments)

32  }

33  // 开始检测更新

34  ngDoCheck() {

35   console.log(2, 'ngDoCheck', this, arguments)

36  }

37  // 数据更新完成

38  ngAfterContentChecked() {

39   console.log(3, 'ngAfterContentChecked', this, arguments)

40  }

41  // 视图更新完成

42  ngAfterViewChecked() {

43   console.log(4, 'ngAfterViewChecked', this, arguments)

44  }

45  // 组件即将销毁

46  ngOnDestory() {

47   console.log(1234, 'ngOnDestory', this, arguments)

48  }

49 }

50 

 

1.3管道

管道就是vue中的过滤器,我们可以在插值语法中,也可以在指令中,使用管道,来处理渲染到页面中的数据。

ng6内置了大量的管道,我们可以使用使用,并处理数据

语法  {{数据 | 管道名称 : 参数1 : 参数2 | 管道2}}

前一个管道的输出结果,将作为下一个管道的输入

1.3.1内置管道

number管道

用来处理数字,变成可读性强的格式,

整数部分每三位添加逗号

默认保留三位小数,最后一位四舍五入

参数表示格式化的字符串

slice管道

切割数组或者字符串

第一个参数表示起始位置

第二个参数表示结束位置(不包含)

data管道

可以创建出任何格式的日期。

参数

可以是内置的日期模板名称,

默认是mediumDate

可以是模板标识

y  代表年

M  代表月

d  代表日

E  代表星期

H | h 代表小时

m  代表分

s  代表秒

...

个数的不同会渲染出不同的格式,通常来说

四位 四位数或者英文全拼

三位 三位数或者英文简写

两位 两位数字

一位 一位数字

<!-- 使用管道 -->

<h1>{{num | number : '1.0-4'}}</h1>

<h1>{{msg | slice : 3 : 7}}</h1>

<h1>{{colors | slice : 2 : 4}}</h1>

<h1>{{date | date}}</h1>

<h1>{{date | date : 'mediumDate'}}</h1>

<!-- 09-22 09:16 -->

<h1>{{date | date : 'MM-dd hh:mm'}}</h1>

<!-- 2018-09-22 -->

10 <h1>{{date | date : 'yyyy-MM-dd'}}</h1>

11 

 

1.3.2自定义管道

内置的管道是有限的,我们想复用更多的逻辑,我们就要自定义管道

跟创建自定义指令,组件,类等一样,我们可以通过ng g指令创建

ng g pipe 管道名称(添加路径的)

创建了两个文件,并且更新了全局模块文件

图片2.png 

自定义的管道被全局声明了,因此我们可以在任何位置使用它

图片3.png 

注解

管道中,通过Pipe管道注解类为管道类注入一些信息

通过name属性定义它的名字

转换方法

管道类中transform方法用来处理数据的,每次数据更新,都会执行

第一个参数表示处理的数据

从第二个参数开始,表示传递的数据

返回值就是渲染的结果

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({

name: 'tocamel'

})

export class TocamelPipe implements PipeTransform {

transform(value: string, firstCharIsUpper?: boolean): string {

 // 如果首字母大写

10   if (firstCharIsUpper) {

11    value = value[0].toUpperCase() + value.slice(1);

12   }

13   // console.log(arguments)

14   // value中的_-去掉,并且后面紧跟的小写字母大写

15   return value.replace(/[-_]([a-z])?/g, (match, $1 = '') => $1.toUpperCase())

16   // return null;

17   // return '爱创课堂';

18  }

19 

20 }

21 

 

1.4数据双向绑定

vue中通过v-model指令实现数据双向绑定

ng6也是基于MVVM模式实现的,因此也支持数据双向绑定,也是通过ngModel指令实现的

数据双向绑定有两个方向

数据由模型进入视图

通过数据绑定实现,就要为该指令绑定一个变量,因此要使用[]语法糖

数据由视图进入模型

通过事件监听实现,就是要为指令绑定一个事件,因此要使用()语法糖

因此在ng6中,实现数据双向绑定,我们就要使用两个语法糖[], ()

绑定的数据,一定要在组件类中声明

我们要先绑定实现,再绑定数据,因此将()写在[]的内部

语法 [(ngModel)]=key

如果页面中,表单元素非常多,此时绑定的数据就多了,为了访问方便,通常我们将其放在同一个命名空间内,但是为了让ng6能够接收这些,就要了解命名空间的结构,因此我们可以定义模型类来说明

注意:我们使用数据双向绑定,是使用表单模块的内容,因此我们要安装表单模块

在全局配置中,引入formModel模块。在imports配置中,注入该模块,此时就可以在任何位置使用表单模块了

<p>

<label>用户名</label>

<!-- 使用数据双向绑定 -->

<!-- <input type="text" [(ngModel)]="username"> -->

<input type="text" [(ngModel)]="data.username">

<span>{{username}}</span>

</p>

<p>

<label>密码</label>

10  <!-- <input type="text" [(ngModel)]="password"> -->

11  <input type="text" [(ngModel)]="data.password">

12 </p>

13 <p>

14  <button (click)="showResult()">查看数据</button>

15 </p>

 

1.5表单校验

当我们与表单元素产生交互,我们就会对表单元素输入信息数据,输入的信息是否合法呢,ng6提供表单校验技术

当我们在页面中,使用form元素的时候,全局安装了formsModule模块。此时就会对form元素自动添加一个ngForm指令,我们可以通过模板变量技术查看ngForm指令对象

#f=ngForm

由于我们为f变量赋值了,因此f就代表了表单指令对象,而不是源生DOM元素了

我们可以将该变量传递给事件回调函数,查看具体信息。

1.5.1四个属性

表单指令对象有四个属性

dirty  是否输入过

true 表示输入过

false 表示未输入过

pristine 是否未输入过

true 表示未输入过

false 表示输入过

所以dirtypristine是一对相反的(互斥)

valid  是否合法

true 表示合法的

false 表示非法的

invalid 是否非法

true 表示非法

false 表示合法

所以validinvalid是一对相反(互斥)

表单指令对象中,有一个controls属性,存储所有子表单元素,跟表单指令对象一样,也具有这四个属性

想在controls属性中,出现子表单元素指令对象,有两个条件

1 必须使用ngModel指令

2 必须定义name属性

通过这四个字段我们可以对表单输入的数据做校验

1.5.2表单约束

ng6中表单元素支持h5提供了表单约束属性,如requiredmaxlengthminlengthpattern等等

其中required在输入前就开始校验了

我们可以通过这些属性对表单元素进行约束。此时validinvalid就有作用了

我们可以根据表单的四个属性,来显隐表单的提示文案,

vue中,内置v-show,用来控制元素显隐,但是在ng6中,显隐元素可以通过h5属性hidden实现,或者自定义显隐指令,如icktShow

对于hidden属性来说,如果属性值

true:隐藏这个元素

false:显示这个元素

为了让变量控制hidden属性值,我们要使用[]语法糖

ng6中,为了方便访问子元素指令对象,允许我们在该元素上通过模板变量获取该指令对象

#key=ngModel

总结

如果有一个子表单元素是输入过的, 表单就是输入过

如果有一个子表单元素是非法的,表单就是非法的

1.5.3提交数据

我们可以通过按钮触发submit事件,提交数据,submit要绑定给form表单元素,并且有提交按钮触发

我们可以通过h5提供的disabled属性控制表单元素是否可以被操作

属性值为true,禁用表单元素

属性值为false,可以使用表单元素

<!-- 绑定提交事件 -->

<form #f="ngForm" (submit)="submitData()">

<p>

 <label>用户名</label>

 <input type="text" autocomplete="off" name="username" [(ngModel)]="data.username" maxlength="10" minlength="4" required #username="ngModel">

 <!-- 未输入要隐藏,或者,合法后也要隐藏 -->

 <!-- <span [hidden]="(f.controls.username && f.controls.username.pristine) || (f.controls.username && f.controls.username.valid)">用户名4-10</span> -->

 <!-- 简便方式 -->

 <!-- <span [hidden]="username.pristine || username.valid">用户名4-10</span> -->

10   <!-- 输入后,并且,不合法 -->

11   <span [icktShow]="username.dirty && username.invalid">用户名4-10位任何字符</span>

12  </p>

13  <p>

14   <label>密码</label>

15   <input type="text" autocomplete="off" name="password" [(ngModel)]="data.password" pattern="^\w{4,8}$" required #password="ngModel">

16   <!-- 输入前,或者,合法 -->

17   <span [hidden]="password.pristine || password.valid">密码是字母数字,下划线,4-8</span>

18  </p>

19  <p>

20   <!-- 查看表单指令对象 -->

21   <!-- <button (click)="showResult(f)">查看数据</button> -->

22   <!-- 表单不合法,不能提交 -->

23   <button [disabled]="f.invalid">提交</button>

24  </p>

25 </form>


1.6异步请求服务

我们为了获取服务器端的数据,我们就要发送异步请求

ng6中,核心模块没有包含http请求模块,因此我们要先安装该模块,再使用该模块

安装http模块服务,跟安装forms模块服务是一样

 app-module.ts中通过imports引入httpModule

imports: [ HttpModule ]

全局配置服务之后,我们就可以在各个组件中使用该服务了

使用http服务,跟使用ElementRef服务一样,也需要先注入,再使用

为了保证服务存储在组件中,我们可以使用publicprivate, protected等关键字注入服务

http模块中的ajax方法,实现了ES6rxjs规范,跟primise规范相似,也是一个将异步写法变同步写法的规范,rxjs是一个发布订阅者模式

http模块提供了

get方法,发送get请求

post方法,发送post请求

使用方式跟axios模块是一样的

但是http的异步请求方法,要通过subscribe方法监听数据返回

返回的数据方法,要调用tojson方法,才能转化成js数据

 

import { Component, OnInit } from '@angular/core';

// 引入服务

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

@Component({

selector: 'app-http',

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

styleUrls: ['./http.component.css']

})

10 export class HttpComponent implements OnInit {

11  msg;

12  // 注入服务

13  constructor(public http: Http) { }

14 

15  ngOnInit() {

16   // 发送请求了

17   this.http.get('/assets/data/msg.json')

18    // 监听数据返回

19    .subscribe(res => {

20     // console.log(res.json())

21     // 根据返回的数据,更新msg

22     let data = res.json();

23     this.msg = data.msg;

24    })

25  }

26 

27 }

28 

 

1.7自定义服务

服务就是对一些方法的封装,让这些方法可以在组件之间复用。

内置的服务是有限的,有时候需要更多的服务,我们要自定义服务

ng g service 服务名称

此时新建了两个文件,并没有更新全局配置文件,因此我们要先配置再使用

图片4.png 


 全套angular视频教程,请添加微信“haomei0452”

微信个人号二维码.jpg

关注微信公众号“icketang”,获取最新前端资讯,学习资料

公众号二维码 .jpg

B站搜索“爱创课堂网络科技” 免费观看前端视频以及项目实战


QQ图片20190401143635.jpg

上一篇文章: Web前端三大框架_angular.js 6.0(二)
下一篇文章: 前端开发——Ionic 3.0

最新发布 | 这里有最新的文章查看更多>>

爱创推荐 | 这里有推荐的文章查看更多>>