Angular组件通信和指令的使用

Posted 公众号_前端每日技巧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Angular组件通信和指令的使用相关的知识,希望对你有一定的参考价值。

Angular组件通信和指令的使用_语法糖

组件通信

组件是一个完整独立的,因此彼此之间的数据不会共享,想在组件之间共享数据,就要实现组件间的通信

组件间通信

父组件向子组件通信

子组件向父组件通信

ng6为了实现组件间通信,提供了吞吐器:Input,Output

父组件向子组件通信

ng6基于ts实现,因此通信的数据要定义类型(了解内部的结构,分配内存空间)

父组件向子组件通信,子组件是接收方,因此要使用Input吞吐器

实现父组件向子组件通信分成6步

第一步 父组件模板中,为子组件传递数据,如果数据是动态可变的,可以使用[]语法糖

第二步 定义数据模型类(如果数据非常简单,可以省略该步)

定义模型类也可以使用ng指令

ng class 类名

模型类的命名规范:我们可以定义成.model.ts文件。也可以将文件直接放在models目录下,并定义成.ts文件

第三步 子组件中,引入模型类

第四步 子组件中,引入吞吐器Input

第五步 通过吞吐器,接收数据,有两种方式

第一种 通过Input吞吐器注解类的方式,接收数据

@Input() 数据名称: 模型类;

第二种 还可以通过组件的注解元信息inputs接收

注解类中:inputs: ​​[属性数据]​

组件中:属性数据: 模型类;

第六步 使用数据,由于数据被添加给组件自身了,因此不论是在组件中,还是在模板中都可以使用

举例:

// 4 引入吞吐器
import Component, OnInit, Input from @angular/core;
// 3 引入模型类
import Data from ../../models/data;
@Component(
selector: app-inputs,
templateUrl: ./inputs.component.html,
styleUrls: [./inputs.component.css],
// 5 通过元信息接收
inputs: [color, data]
)
export class InputsComponent implements OnInit
// 5 接收数据
// @Input() data: Data;
// @Input() color: string;
// 声明类型
data: Data;
color: string;
constructor()
// 6 组件中使用
console.log(this)

ngOnInit()

子组件向父组件通信

子组件向父组件通信是基于自定义事件实现的。对于子组件来说,是发布方,因此要使用Ouput吞吐器

实现子组件向父组件通信分成六步

第一步 在父组件模板中,模拟DOM事件,为子组件元素绑定父组件的方法,使用()语法糖

例如 (demo)=”dealDemo($event)”

为了传递数据,要添加$event

第二步 在子组件中,引入吞吐器 Output

第三步 在子组件中,引入EventEmitter事件模块

第四步 为子组件创建事件对象,有两种方式

第一种 通过Output吞吐器注册

@Output() 属性名称 = new EventEmitter()

第二种 还可以通过注解的元信息outputs接收

在注解中,注册属性   outputs: ​​[属性名称]​

组件中,创建事件对象 属性名称 = new EventEmitter()

第五步 子组件中,通过事件对象的emit方法发布消息,参数就是传递的数据

第六步 在父组件中,通过父组件方法,接收子组件传递的数据

import  Component, OnInit, Output, EventEmitter  from @angular/core;
@Component(
selector: app-outputs,
templateUrl: ./outputs.component.html,
styleUrls: [./outputs.component.css],
// 元信息注册事件对象
outputs: [sendMessage]
)
export class OutputsComponent implements OnInit
// 4 注册事件对象
// @Output() sendMessage = new EventEmitter();
// 实例化
sendMessage = new EventEmitter();
constructor()
ngOnInit()

// 事件回调函数
demo()
// console.log(111, this)
// 5 点击按钮的时候,向父组件发布消息
this.sendMessage.emit(
msg: hello菜鸟,
color: red
)


自定义指令

在ng6中,指令共分三类

第一类指令:就是组件(组件也是指令)

第二类指令:属性型指令,如:ngStyle,ngClass等

用来控制元素的属性行为的。

ngClass跟vue中绑定类语法一样

属性值

可以是数组

可以是对象

可以是字符串

第三类指令:结构型指令,如:ngIf, ngSwitchCase, ngSwitchDefault, ngFor

用来控制元素的创建的(也是模板指令)

属性型指令与结构型指令区别

1 属性型指令控制元素的属性行为,不负责元素的创建,而结构型指令则控制元素的创建

2 指令的属性值默认都是字符串,想变成js环境都要使用语法糖

属性型指令语法糖: ​​[]​

结构型指令语法糖: 普通元素上使用 * , 模板元素上使用​​[]​

创建指令

内置的指令是有限的,想实现更多的功能,我们要自定义指令,ng6也为我们提供了创建指令的工具

通过 ng g directive 指令名称

会自动创建指令脚本文件和指令单测文件,

并且修改app.module全局模块文件,在全局声明了,因此在模块内部的所有组件中,都可以直接使用该指令。

指令与组件

指令与组件的区别

1 文件

组件有四类文件:样式,模板,脚本,单测

组件只有两类文件:脚本,单测

2 选择器

组件是自定义元素名称选择器

指令是自定义属性名称选择器

3 OnInit接口

组件实现了OnInit接口

指令没有实现OnInit接口

4 注解

组件的组件类是Component

指令的注解类是Directive

组件也属于指令,组件之间可以通信,组件与指令之间也可以通信

指令向组件通信

由于指令在组件中使用,所以指令向组件的通信可以看成是子组件向父组件通信

分成六步

第一步 绑定自定义事件

第二步 指令中,引入吞吐器Output

第三步 指令中,引入EventEmitter

第四步 注册事件对象,有两种方式

1 吞吐器:  @Output() demo = new EventEmitter()

2 元信息: 注解中outputs: [] 组件中 deom = new EventEmitter()

第五步 指令发布消息,通过emit方法

第六步 父组件接收数据,并使用数据

举例:

import  Directive, Output, EventEmitter  from @angular/core;
@Directive(
selector: [appDemo],
// 元信息
outputs: [sendMessage]
)
export class DemoDirective
// 4 注册消息
// @Output() sendMessage = new EventEmitter();
// 初始化
sendMessage = new EventEmitter();
constructor()
// console.log(success)
// 2秒钟之后发送
setTimeout(() =>
// 5 发布消息
this.sendMessage.emit(
color: pink,
msg: 菜鸟学习
)
, 2000)

组件向指令通信

同样的道理,组件向指令通信,我们也可以看成是父组件向子组件通信,

共分六步

第一步 传递属性数据(如果是变化的,要使用[]语法糖)

第二步 定义模型类

第三步 指令中,引入模型类型

第四步 指令中,引入吞吐器Input

第五步 注册数据

1 吞吐器: @Input() demo:Data;

2 元信息: 注解中inputs: ​​[]​​, 组件中 demo:Data;

第六步 指令中使用数据


模板指令

指令是对DOM的拓展,为元素提供更多的功能。

在ng6中,只能要使用驼峰式命名,并且属性值是字符串, 例如 ngStyle=””

让指令的属性值变成js环境,我们要使用​​[]​​语法糖

为了控制元素的创建,ng6提供了一组模板指令

一个指令只能控制一个元素,想控制多个元素,我们要使用模板组件

模板组件

在vue中,通过template定义模板组件

在ng6中,通过ng-template定义模板组件

是一个模板组件,默认不会渲染出来,但是可以像元素一样,添加属性等等

在ng6中模板组件跟普通的元素不同的,在使用模板指令的时候语法不一样

普通的元素,使用模板指令,要使用*语法糖

ng-template模板组件,使用模板指令,要使用​​[]​​语法糖

条件模板指令

在vue中,通过v-if定义条件模板指令

在ng6中,通过ngIf定义条件模板指令

对普通元素使用,要使用*语法糖。

对模板组件使用,要使用[]语法糖

使用语法糖后,属性值是js环境

值为true要创建该元素

值为false要删除该元素。

多分支条件模板指令

在vue中,通过v-if,v-else-if,v-else等指令定义多分支条件模板指令

在ng6中,通过模拟js中switch语句实现的

js中定义switch语句

swtich () 

case:;

case:;

default:;

ng6提供了ngSwitch,ngSwitchCase,ngSwitchDefault指令,实现多分支条件模板指令

通过ngSwitch定义条件,没有控制元素创建,所以要使用[]语法糖

ngSwitchCase与ngSwitchDefault要控制元素的创建,因此要使用*语法糖

ngSwitchCase的属性值是条件值,是js环境,字符串要加引号

ngSwitchDefault不需要设置属性值

举例:

<!-- 普通元素使用*语法糖 -->
<h1 *ngIf="isShow">template works!</h1>
<!-- 控制多个元素 -->
<ng-template [ngIf]="isShow">
<h1>学习</h1>
<h2>菜鸟学习</h2>
</ng-template>
<!-- 选项卡 -->
<button (click)="togglePage(home)">home</button>
<button (click)="togglePage(list)">list</button>
<button (click)="togglePage(detail)">detail</button>
<!-- 定义三个页面 -->
<div [ngSwitch]="page">
<!-- 定义条件 -->
<h1 *ngSwitchCase="home">home page</h1>
<h1 *ngSwitchCase="abc">list page</h1>
<!-- 默认的 -->
<h1 *ngSwitchDefault>detail page</h1>
</div>
<h1>page</h1>

循环模板指令

vue中,循环模板指令通过v-for=”item in data”

ng6中,循环模板指令通过ngFor定义的

语法 ​​*ngFor=”let item of data” ​

let和of表示关键字

data 表示遍历的数据

item 表示成员值

除了item循环变量之外,还提供了一些循环变量

index 索引值

first 是否是第一次

last 是否是最后一次

odd 是否是奇数次

even 是否是偶数次

注意:计算机是从0开始计数的,因此

计算机中的偶数次,就是人看到的奇数次

计算机中的奇数次,就是人看到的偶数次

虽然存在这些循环变量,但是我们无法直接使用,必须先定义再使用

index as $index

此时$index就代表索引值了

当使用循环模板指令控制多个元素的时候,就要使用模板组件ng-template

此时语法有些改变

ngFor 声明循环指令

​[ngForOf]=”data”​​  定义循环的数据

let-item 定义循环变量

举例:

<ul>
<li *ngFor="let item of colors; index as index; first as f; last as $last; even as even; odd as odd">item--index--f--$last--even--odd</li>
<li *ngFor="let item of colors; index as index; first as f; last as $last; even as even; odd as odd" [style.backgroundColor]="even ? #efefef : yellowgreen">item--index--f--$last--even--odd</li>
</ul>
<!-- 控制多个元素,使用模板标签 -->
<ul>
<ng-template ngFor [ngForOf]="colors" let-item>
<h1>item</h1>
<h2>item</h2>
</ng-template>
</ul>

以上是关于Angular组件通信和指令的使用的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 1.x 中通信组件或指令的有效方式

angular 自定义指令详解 Directive

Angular 混合应用程序中降级组件中无法识别的驼峰式参数

Angular (v2) 扩展系列组件通信(无父或外部服务)

Angular 2 阅读更多指令

Angular框架中的父子组件通信传递异步的数据接收值异常的问题(Async Data)