angular——子组件如何接收父组件的动态传值

开发过程中,父组件给子组件传值的情况很常见,今天我们就来聊聊父组件给子组件传值可能会发生哪些意外,什么情况下子组件无法接收到父组件最新的传值;

传值情况:

  1. 基本数据类型:父组件给子组件传递 基本数据类型,子组件使用变量接收传值;当传值发生变化,子组件接收的值也会跟着变化;

  2. 引用数据类型:当父组件传递给子组件的 数据对象(对象或引用类型) 发生变化时,子组件接收到的值不一定会跟着变化;

以下是一些情况下子组件中的变量不会自动更新的场景:

  1. 输入属性为对象或引用类型: 如果父组件传递给子组件的输入属性是一个对象或引用类型(如数组);
    并且在父组件中修改了该对象的属性或对其进行了重新赋值,子组件中的变量本身不会发生变化。
    原因:变更检测机制只会检测到对象或引用本身的变化,而不会深度观察对象内部的属性或内容的变化。
    在这种情况下,需要手动处理以确保子组件中的变量更新,可以使用 OnChanges 生命周期钩子、set方法接收、订阅 Input 属性的变化来实现。
  2. 使用 @ViewChild 或服务来共享数据: 如果父组件通过 @ViewChild 或服务(例如共享服务)来传递数据给子组件,子组件中的变量通常不会自动更新。这是因为 @ViewChild 或服务提供的数据是一个单独的实例,与父组件中的数据不直接关联。在这种情况下,需要手动更新子组件中的变量,例如使用订阅机制或事件触发等方式。

举例说明:

1. 子组件使用set方法接收传值

// 父组件
@Component({selector: 'app-parent',template: `<app-child [data]="parentData"></app-child><button (click)="changeData()">Change Data</button>`
})
export class ParentComponent {parentData = { value: 'Initial data' };changeData() {this.parentData.value = 'Updated data';}
}// 子组件
@Component({selector: 'app-child',template: `<p>{{ childData }}</p>`
})
export class ChildComponent {private _data: any;@Input()set data(value: any) {this._data = value;// 在这里可以对数据进行进一步处理}get childData(): any {return this._data;}
}

在上述示例中,父组件通过 parentData 对象将数据传递给子组件的 data 输入属性。子组件使用 set 方法接收该数据,并将其存储在私有变量 _data 中。

当点击 “Change Data” 按钮时,父组件的 changeData() 方法将修改 parentData.value 的值为 ‘Updated data’。此时,子组件中的 set 方法会被触发,并接收到新的数据对象 { value: ‘Updated data’ }。子组件可以在 set 方法内部对数据进行相应的处理以更新子组件的状态。

set 方法的触发是由 Angular 的变更检测机制 自动处理的,无需手动触发该方法。

set 方法触发时机

  1. 初始化时触发: 当父组件传递的数据被子组件初始化时,set 方法会在子组件创建和渲染过程中首次触发。这是设置初始值的时机。

  2. 属性变化时触发: 如果父组件的数据发生了变化(例如由于用户交互或异步请求等),Angular 的变更检测机制会检测到属性的变化,并触发子组件中的 set 方法,从而更新子组件的相应属性。

get 方法触发时机

get 方法的触发是由子组件主动读取属性值时自动触发的,而不是由 Angular 的变更检测机制触发的。因此,它并不会在每次属性变化时都触发。只有当子组件需要获取属性值时,get 方法才会被调用。
例如,在子组件的模板中使用插值表达式、绑定属性、或者在子组件的 TypeScript 代码中直接访问该属性时,get 方法会被调用。

2. 使用 ngOnChanges 生命周期钩子

在该钩子中监听父组件传入的输入属性变化,并在变化时手动更新子组件内部的变量。通过 SimpleChange 对象可以获取到新值和旧值进行比较,从而进行相应的处理。

// 父组件
@Component({selector: 'app-parent',template: `<app-child [data]="parentData"></app-child><button (click)="changeData()">Change Data</button>`
})
export class ParentComponent {parentData = { value: 'Initial data' };changeData() {this.parentData.value = 'Updated data';}
}// 子组件
@Component({selector: 'app-child',template: `<p>{{ childData }}</p>`
})
export class ChildComponent implements OnChanges {@Input() data: any;childData: any;ngOnChanges(changes: SimpleChanges) {if (changes.data && changes.data.currentValue) {this.childData = changes.data.currentValue;}}
}

3. ViewChild 使用static: false 传递数据

如果父组件通过 @ViewChild 或服务(例如共享服务)来传递数据给子组件,并且使用 static: true,那么当父组件的值发生变化时,子组件通常不会自动更新。

相反,使用 static: false,那么当父组件的值发生变化时,子组件也会相应地更新。

原理:
当使用 @ViewChild 来获取对子组件的引用时,如果将 static 设置为 false,它会使得 @ViewChild
成为一个查询,会在每次变更检测时重新查询子组件。这意味着如果父组件的值发生变化,子组件的引用会重新查询并得到更新。

在父组件中,通过 @ViewChild 获取子组件的引用,并传递值给子组件:

import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';@Component({selector: 'app-parent',template: `<app-child></app-child><button (click)="updateData()">Update Parent Data</button>`
})
export class ParentComponent {@ViewChild(ChildComponent, { static: false })childComponent: ChildComponent;parentData = { name: 'John', age: 25 };updateData(): void {this.parentData = { name: 'Jane', age: 30 };this.childComponent.data = this.parentData;// 或者调用子组件的方法进行更新:this.childComponent.updateData(this.parentData);}
}

在子组件中,定义一个属性来接收父组件的值,并在模板中显示该数据:

import { Component, Input } from '@angular/core';@Component({selector: 'app-child',template: `<div>Name: {{ data.name }}</div><div>Age: {{ data.age }}</div>`
})
export class ChildComponent {@Input()data: any;}

在上述示例中,当父组件的 updateData 方法被调用时,它会更新 parentData 的值,并将新值传递给子组件的 data 属性。由于 @ViewChild 使用了 static: false,子组件的引用会重新查询,在变更检测期间子组件会获取到新的值并进行更新。

总结来说,如果你使用 @ViewChild 并设置了 static: false,当父组件的值发生变化时,子组件也会随之更新。这使得父组件能够直接影响到子组件的状态和行为。

4. ViewChild 使用static: true 传递数据

使用 @ViewChild 来获取对子组件的引用时,如果将 static 设置为 true,它会使得 @ViewChild 成为一个静态查询,只在 组件初始化时 进行一次查询。这意味着子组件只会获取到父组件初始时的值,并且不会随着父组件值的变化而自动更新。

在这种情况下,需要手动更新子组件中的变量以反映父组件的变化。可以使用订阅机制、事件触发等方式,在父组件的值发生变化时通知子组件进行更新。

import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';@Component({selector: 'app-parent',template: `<app-child></app-child><button (click)="updateData()">Update Parent Data</button>`
})
export class ParentComponent {@ViewChild(ChildComponent, { static: true })childComponent: ChildComponent;parentData = { name: 'John', age: 25 };updateData(): void {this.parentData = { name: 'Jane', age: 30 };this.childComponent.updateData(this.parentData); // 手动更新子组件中的变量}
}

在子组件中,定义一个方法来接收父组件的值,并在模板中显示该数据:

import { Component } from '@angular/core';@Component({selector: 'app-child',template: `<div>Name: {{ data.name }}</div><div>Age: {{ data.age }}</div>`
})
export class ChildComponent {data: any;updateData(newData: any): void {this.data = newData;}
}

在上述示例中,当父组件的 updateData 方法被调用时,它会更新 parentData 的值,并手动调用子组件的 updateData 方法来更新子组件中的变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/32625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用logstash将graylog日志传输到kafka中

1.graylog配置输出 在System-outputs&#xff0c;选择GELF Output&#xff0c;填写如下内容&#xff0c;其它选项默认 在要输出的Stream中&#xff0c;选择Manage Outputs 选择GELF Output&#xff0c;右边选择刚才创建好的test。 2.安装logstash&#xff0c;作为中间临时…

《Java-SE-第三十四章》之Optional

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…

C#小轮子:Visual Studio自动编译Sass文件

文章目录 前言插件安装插件使用compilerconfig.jsonsass输入和css输出&#xff08;自动生成&#xff09;默认配置&#xff08;我不懂就不去动他了&#xff09; 前言 我们知道css文件用起来太麻烦&#xff0c;如果样式一多&#xff0c;嵌套起来用css样式就眼花缭乱。Sass使用层…

Kafka的下载和安装

一、Kafka下载和安装 下载地址&#xff1a;https://kafka.apache.org/downloads 下载完毕解压即可 linux解压命令tar -zxvf kafka_2.13-3.5.1.tgz&#xff0c;linux环境下指令是在\kafka_2.13-3.5.1\bin目录。 windows直接解压即可&#xff0c;windows环境下指令是在kafka_2.…

强化学习-信任区域策略优化和近端策略优化(第7章)

来源书籍&#xff1a; TENSORFLOW REINFORCEMENT LEARNING QUICK START GUIDE 《TensorFlow强化学习快速入门指南-使用Python动手搭建自学习的智能体》 著者&#xff1a;[美]考希克巴拉克里希南&#xff08;Kaushik Balakrishnan&#xff09; 译者&#xff1a;赵卫东 出版…

Rust 编程小技巧摘选(7)

目录 Rust 编程小技巧(7) 1. 交换变量 2. 翻转数组 3. for_each() 用法 4. 结构体 Display trait 5. HashMap 和 BTreeMap 6. 遍历输出哈希表 7. 分离奇数和偶数 8. 判断素数&#xff08;质数&#xff09; Rust 编程小技巧(7) 1. 交换变量 与python, go等语言用法类…

计算机网络:网络字节序

目录 一、字节序1.字节序概念2.字节序的理解&#xff08;1&#xff09;大端模式存储数据&#xff08;2&#xff09;小端模式存储数据 二、网络字节序 一、字节序 1.字节序概念 字节序&#xff1a;内存中存储多字节数据的顺序。 难道存储数据还要看顺序吗&#xff1f; yes。内…

python读入和读出图像

python提供了PIL库和opencv库对图像进行读取并保存。 图像读入读出 给定一张RGB的彩色图像&#xff0c;PIL库将其读入: import cv2 from PIL import Image # 读入图像 image2 Image.open(cub1.jpg) print(type(image2)) image2_array np.array(image2) print(image2_array…

【将回声引入信号中】在语音或音频文件中引入混响或简单回声,以研究回声延迟和回波幅度对生成的回波信号感知的影响(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Golang字符串处理深入解析:探索 strings 标准库的全部方法

Golang 的 strings 标准库提供了许多用于处理字符串的函数。以下是一些主要的方法&#xff1a; Contains(s, substr string) bool: 检查字符串是否包含子串。ContainsAny(s, chars string) bool: 检查字符串是否包含字符集中的任何字符。ContainsRune(s string, r rune) bool:…

Java 正则表达式【匹配与分组基本原理】

简介 我们一般使用正则表达式是用来处理字符串的&#xff0c;不管是实际的开发中还是我们的算法竞赛中&#xff0c;使用正则表达式绝对可以大大提升我们的效率。 正则表达式&#xff08;regular expression&#xff09;其实就是对字符串进行模式匹配的技术。 快速入门 我们这里…

第三篇|金融人数据来源有哪些

数据对于金融行业真的很重要&#xff0c;那么金融人有哪些途径查数据呢&#xff1f; 国内&#xff1a; 1. 国家统计局 这个应该是无论什么行业都使用最频繁的网站&#xff0c;每个月都会固定发上个月资产投资数据 、工业增加值和利润数据等常规数据&#xff0c;其他数据也会…

06 Word2Vec模型(第一个专门做词向量的模型,CBOW和Skip-gram)

博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https://github.com/nickchen121/Pre-training-language-model 配套博客链接:https://www.cnblogs.com/nickchen121/p/15105048.html 神经网络语言模型(NNL…

什么是分布式系统,如何学习分布式系统

正文 虽然本人在前面也写过好几篇分布式系统相关的文章&#xff0c;主要包CAP理论&#xff0c;分布式储存与分布式事务&#xff0c;但对于分布式系统&#xff0c;并没有一个跟清晰的概念。分布式系统涉及到很多的技术、理论与协议&#xff0c;很多人也说&#xff0c;分布式系统…

git实用命令 git常用分支命令

一、git创建本地分支 要在Git中创建一个新的分支&#xff0c;按照以下步骤进行操作&#xff1a; 确保你当前在要创建分支的代码状态下。你可以使用 git status 命令查看当前的代码状态&#xff0c;并使用 git add 和 git commit 命令将修改的文件提交到当前分支。 1.使用 gi…

Docker 安装和架构说明

Docker 并非是一个通用的容器工具&#xff0c;它依赖于已存在并运行的Linux内核环境。 Docker实质上是在已经运行的Liunx下制造了一个隔离的文件环境&#xff0c;因此他的执行效率几乎等同于所部署的linux主机。因此Docker必须部署在Linux内核系统上。如果其他系统想部署Docke…

hutool 导出复杂表头excel

假如已这样的表头导出数据 1.把包含表头的excel添加到项目资源目录 2.编写代码读取表头所在sheet,并且加入需导出的数据 /*** 导出excel*/public static void downloadExcel(List<List<Object>> list, HttpServletResponse response) throws IOException {/*Strin…

OpenCV(三)——图像分割(二)

目录 4.边缘检测 4.1 图像梯度的概念 4.2 模板卷积和梯度图的概念 4.3 梯度算子

wpf 3d 坐标系和基本三角形复习

wpf 3d 坐标系的描述见此&#xff0c; WPF 3d坐标系和基本三角形_wpf 坐标系_bcbobo21cn的博客-CSDN博客 X轴正向向右&#xff0c;Y轴正向向上&#xff1b;Z轴&#xff0c;正向是从屏幕里边出来&#xff0c;负向是往屏幕里边去&#xff1b;坐标原点是在呈现区域的中心&#x…

知识付费系统开发:构建高效智能的付费内容平台

随着数字化时代的来临&#xff0c;知识付费正迅速崭露头角&#xff0c;为知识创作者和求知者带来了全新的商机。在这个背景下&#xff0c;开发一款高效智能的知识付费系统成为了一项重要的任务。本文将深入探讨如何基于Python编程语言和相关技术构建一个智能的知识付费内容平台…