如何通过简单的代码描述Angular父组件、子组件传值


Posted in Javascript onApril 07, 2022

引言

对于稍微接触过Angular组件的同学来说,组件间交互应该没有什么问题。

本文想追求的是用一个通俗解释,帮助自己理解的更准确。

零、知识铺垫

CSS选择器

在介绍父子组件之前,先要了解一个概念——selector、选择器

我们定义一个新组件时,一定会有这个属性:

@Component({
  selector: 'app-village-edit', ①
  templateUrl: './village-edit.component.html',
  styleUrls: ['./village-edit.component.scss']
})

其中①就是选择器,就是告诉别的组件,如果想调用我这个组件,就要使用本组件的选择器<selectorName></selectorName>来调用。

本质上就是定义了组件的HTML标签,就像常见的<p>标签、<button>标签一样。

一、什么是父子组件

就像现实中父母和孩子的关系是相对的一样,一个人对于它的父母来说,就承担了孩子的角色;对于它的孩子来说则承担了父母的角色。

父组件和子组件也是相对的。

假设,一个组件在自己的HTML模板中,通过选择器(也就是特定的HTML标签)来调用其他组件时。我们称这个组件为父组件,而那个被调用的组件称为子组件

二、父组件调用子组件的方法

定义了两个类:

child.component.ts,它的选择器selector是: 'app-child'

parent.component.ts,它的选择器selector是: 'app-parent',

此时,在parent组件的HTMl中引用child组件的选择器:

<app-child></app-child>

这样就完成了子组件的调用。
此时,如果通过路由加载父组件,就会发现子组件也会在特定的位置被渲染出来。

三、父组件向子组件传值

子组件使用@input装饰器接收数据

子组件从父组件接收的值,会保存到子组件的变量中。

所以用来接收传值的变量与普通变量唯一的区别,就是在常规的变量上增加一个@input()注解。

定义普通变量是这样的:

master = 'Master';

如果用来接收传值,只要改成这样:

@Input() master = 'Master';

这样,master变量默认是'Master'字符串。

但如果父组件向其传值,变量就变成了接收的值。

父组件使用方括号[]发送数据

常规方式调用子组件:

<app-child></app-child>

如果子组件可以接收数据,就可以用[propertyName] = value的方法来传值。
例如:

<app-child [master]="hero"> </app-child>

用这种写法可以实现:一旦组件渲染完成后,子组件中的master变量就是'hero'的值了。

当父组件中的变量值变化时,子组件也会同步变化,也就是说,子组件可以监听传过来的值的变化信息

升级:子组件通过set方法监听传入数据变化

在上面的方式中,对于传过来的值,虽然可以监听变化,但局限在于:子组件只能直接使用传入的值。

如果想对传入的值进行处理或过滤,就要稍微调整一下子组件。

常规情况下,子组件是通过给变量加上@Input装饰器来接收参数的:

@Input() name = 'name';

如果想处理参数,只需要把接收传值的变量变成set方法即可:

@Input() 
get name(): string { return this._name; }
set name(name: string) { 
    // 此处可以增加其他处理逻辑
    this._name = name; 
} 
private _name = '';

此时,_name是内部变量,当父组件对于name属性传入值的时候,会自动执行set name方法给_name赋值并增加其他的处理逻辑。

另一种升级:子组件通过ngOnChanges()生命周期钩子监听传入数据变化

官方文档中写到:“当需要监视多个、交互式输入属性的时候,ngOnChanges()比用属性 setter 方法更合适。”

常规情况下,子组件是通过给变量加上@Input装饰器来接收参数的:

@Input() param1 = 'string1';
@Input() param2 = 'string2';

当我们要监听多个变量的变化并做出反应时,可以用ngOnChanges()方法:

@Input() param1 = 'string1';
@Input() param2 = 'string2';

ngOnChanges(changes: SimpleChanges) {  ①

    for (const propName in changes) {  ②
    
        // 通过变量名获取变化信息
        const changedProp = changes[propName];  
        // 获取上一个值
        const from = JSON.stringify(changedProp.previousValue); ③
        // 获取当前值
        const to = JSON.stringify(changedProp.currentValue);     ④
        // 此处可以添加其他处理过程了 ⑤
     } 
     
}

① 执行ngOnChanges()方法时,可以用一个SimpleChanges参数来获得当前组件所有参数的变化情况。

② 通过循环获得每一个参数的上一个值和当前值。

③ 获得上一个值④ 获得当前值⑤ 根据业务逻辑添加其他处理过程

注:由于ngOnChanges方法调用非常频繁,会导致性能问题或者软件崩溃,所以建议少用。

四、子组件向父组件传值

子组件向父组件弹射事件

刚刚讲到了子组件如何获取父组件的传入的变量,如何监听父组件的变化,以及如何处理传入的值。

接下来讲反向的传输:父组件如何监听子组件的变化,并做出反应。

定义普通变量是这样的:

param1 = 'String1';

如果想把这个变量暴露给父组件,需要在变量前加入@output()装饰器,并且给他赋值一个变量弹射器

@Output() param1 = new EventEmitter<string>();

此处EventEmitter是变量弹射器,EventEmitter需要一个确定的类型

但此时,这个param1变量就不能再用等号"="赋值了,如果想让父组件监听到变化,就需要用弹射方法.emit

this.param1.emit("String2");

接下来前往父组件。

父组件监听子组件弹射的事件

刚刚已经在子组件设置好了暴露的变量,那么父组件如何接收呢?

常规的父组件调用子组件:

<app-child></app-child>

如果想监听子组件的某个变量,可以使用圆括号():

<app-child (param1)="function1($event)">

</app-child>

$event 是Angular内置的事件变量。

function1我们在父组件中定义的处理变化的方法。

使用方式如下:

function1(param2: boolean) { 
    // 这个param2为我们自己定义的参数名,
    // 本质上是子组件中变化的param1参数,但不用和子组件中的参数名相同
    // 在此处增加处理过程即可
}

此时,当param1的值发生变化,就会执行function1,并且传入一个事件,事件的实质内容就是子组件定义的param1参数。

function1方法把参数作为param2接收,并添加处理过程。

五、总结

  • Angular中,在HTML通过selector选择器调用的组件称为子组件
  • 父组件向子组件传值使用方括号[]
  • 子组件有两种方式接收值: @input + 变量名、@Input + set方法
  • 子组件想父组件传递事件使用EventEmitter
  • 父组件接收事件使用圆括号(),并声明一个处理方法用来调用

熟悉的风格,一图胜千言:

如何通过简单的代码描述Angular父组件、子组件传值

六、后记

是不是有似曾相识的感觉,在刚开始接触Angular时就知道,可以使用方括号[]来绑定原生HTML标签的某些属性,例如:

<p [id]="sayHelloId" [style.color]="fontColor">
    You can set my color in the component!
</p>

另一方面,还有一个相似之处就是,Angular中也是使用圆括号()来绑定原生HTML标签的某个方法,例如:

<button (click)="onClick()"> 
    点我!
</button>

这些是巧合吗?并不是。

我们可以这样理解:

Angular中所有的原生HTML标签都变成了组件

之所以很多标签中可以用方括号[]绑定属性、使用圆括号()绑定方法,是因为Angular已经为我们扩展了原生的HTML标签,使它们具备了接收和发送数据的能力!

换言之,在Angular内部的组件中,已经为我们加上了许许多多的@input@output装饰器,我们才能方便的绑定这些属性和方法。

总结

到此这篇关于如何通过简单的代码描述Angular父组件、子组件传值的文章就介绍到这了,更多相关Angular父组件、子组件传值内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!


Tags in this post...

Javascript 相关文章推荐
Package.js  现代化的JavaScript项目make工具
May 23 Javascript
Extjs4 GridPanel的主要配置参数详细介绍
Apr 18 Javascript
Jquery chosen动态设置值实例介绍
Aug 08 Javascript
快速解决jQuery与其他库冲突的方法介绍
Jan 02 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
Mar 17 Javascript
jQuery实现响应鼠标背景变化的动态菜单效果代码
Aug 27 Javascript
JS库 Highlightjs 添加代码行号的实现代码
Sep 13 Javascript
Element-ui table中过滤条件变更表格内容的方法
Mar 02 Javascript
vue插件实现v-model功能
Sep 10 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
Jan 09 jQuery
微信小程序身份证验证方法实现详解
Jun 28 Javascript
layui输入框只允许输入中文且判断长度的例子
Sep 18 Javascript
TypeScript 使用 Tuple Union 声明函数重载
Apr 07 #Javascript
Axios代理配置及封装响应拦截处理方式
vue-cil之axios的二次封装与proxy反向代理使用说明
Apr 07 #Vue.js
动态规划之使用备忘录来改进Javascript函数
Apr 07 #Javascript
vue实现拖拽交换位置
Apr 07 #Vue.js
使用Ajax实现进度条的绘制
Vue.Draggable实现交换位置
You might like
快速开发一个PHP扩展图文教程
2008/12/12 PHP
CI框架中zip类应用示例
2014/06/17 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
PHP判断一个数组是另一个数组子集的方法详解
2017/07/31 PHP
Laravel Eloquent分表方法并使用模型关联的实现
2019/11/25 PHP
jquery 框架使用教程 AJAX篇
2009/10/11 Javascript
JQuery 将元素显示在屏幕的中央的代码
2010/02/27 Javascript
前后台交互过程中json格式如何解析以及如何生成
2012/12/26 Javascript
EasyUi combotree 实现动态加载树节点
2016/04/01 Javascript
HTML5 canvas 9绘制图片实例详解
2016/09/06 Javascript
学习vue.js表单控件绑定操作
2016/12/05 Javascript
jQuery实现倒计时重新发送短信验证码功能示例
2017/01/12 Javascript
ES6新特性七:数组的扩充详解
2017/04/21 Javascript
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
微信小程序车牌号码模拟键盘输入功能的实现代码
2018/11/11 Javascript
vue-cli项目使用mock数据的方法(借助express)
2019/04/15 Javascript
[31:33]2014 DOTA2国际邀请赛中国区预选赛 TongFu VS DT 第一场
2014/05/23 DOTA
Python数据结构与算法之图的基本实现及迭代器实例详解
2017/12/12 Python
python3.6使用pymysql连接Mysql数据库
2018/05/25 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
小 200 行 Python 代码制作一个换脸程序
2020/05/12 Python
详解Windows下PyCharm安装Numpy包及无法安装问题解决方案
2020/06/18 Python
Python接口自动化测试的实现
2020/08/28 Python
Django-simple-captcha验证码包使用方法详解
2020/11/28 Python
python热力图实现简单方法
2021/01/29 Python
html5中canvas学习笔记1-画板的尺寸与实际显示尺寸
2013/01/06 HTML / CSS
html5开发三八女王节表白神器
2018/03/07 HTML / CSS
Lentiamo丹麦:购买便宜的隐形眼镜
2021/01/13 全球购物
药学职务聘任书
2014/03/29 职场文书
入党函调证明材料
2014/12/24 职场文书
统计员岗位职责
2015/02/11 职场文书
教师自荐信范文
2015/03/06 职场文书
同学聚会通知短信
2015/04/20 职场文书
2016年“5.12”护士节致辞
2015/07/31 职场文书
诚实守信主题班会
2015/08/13 职场文书
golang协程池模拟实现群发邮件功能
2021/05/02 Golang