Angular组件通信和指令的使用
Posted 公众号_前端每日技巧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 混合应用程序中降级组件中无法识别的驼峰式参数