当前位置: 首页 > news >正文

Angular 由一个bug说起之二:trackBy的一点注意事项

trackBy是angualr优化项目性能的一种方法, 通过返回一个具有绑定性的唯一值, 比如id,手机号,身份证号之类的,来让angular能够跟踪数组的项目,根据数据的变化来重新生成DOM, 这样就节约了性能。

但是如果是使用ngFor循环组件,添加trackBy的时候就需要注意这个组件自身的数据更新机制是否正常,因为没有使用trackBy的时候,for循环的数组数据改变了,angular会把数组里所有的项目都重新生成,那些项目的组件也都会重新初始化。

但当你使用了trackBy,数据发生了变化,angular只会把那些数据有变化的项目重新生成,这样项目的组件也不会重新初始化,如果这个组件的数据更新机制不够好,这时就会因为数据更新的问题,产生bug。

接下来我用一个例子来演示一下

这是子组件test

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';@Component({selector: 'app-test',templateUrl: './test.component.html',styleUrls: ['./test.component.css']
})
export class TestComponent implements OnChanges {@Input() data: any;name: string;age: number;married: boolean;constructor() {}ngOnChanges(changes: SimpleChanges): void {if (changes.data?.currentValue) {this.init(changes.data?.currentValue);}}init(data) {this.name = data.name;this.age = data.age;this.married = this.married !== undefined ? this.married : data.married;}
}
<div><div>姓名: {{ name }} </div><div>年龄: {{ age }}</div><div>婚否: {{ married ? '已婚' : '未婚' }}</div>
</div>

这是父组件app

import { Component } from '@angular/core';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent {itemArray = [{id: 1,data: {name: '张三',age: 24,married: true}},{id: 2,data: {name: '李四',age: 25,married: true}},{id: 1,data: {name: '王五',age: 26,married: false}},];constructor() { }changeData() {this.itemArray = [{id: 1,data: {name: '张三',age: 24,married: false}},{id: 2,data: {name: '李四',age: 25,married: true}},{id: 1,data: {name: '王五',age: 26,married: true}},];}}
<div><div *ngFor="let item of itemArray;"><app-test [data]="item.data"></app-test>------------------------------</div><button (click)="changeData()">changeData</button>
</div>

我在这里循环一个数组,显示人物的资料,姓名,年龄,婚否。

接下来我改变一下数据,调用一下changeData,把张三变成未婚,王五变成已婚

数据正常更新了,这是没有加trackBy的时候,现在添加一下trackBy

trackByFn(index: number, item: any) {return item.id;}
<div><div *ngFor="let item of itemArray; trackBy: trackByFn;"><app-test [data]="item.data"></app-test>------------------------------</div><button (click)="changeData()">changeData</button>
</div>

点击changeData

组件没有重新生成,数据也没有更新,这是因为test组件的更新机制有问题

他这里是以组件本身的数据为先,这样的话,即使上面传下来新数据,他也不会更新,除非重新初始化,而加个trackBy之后,组件就不会重新生成,所以没加trackBy之前,没有bug,加了就有bug。

所以,要使用trackBy,组件本身的数据更新机制要正常才行。

相关文章:

  • excel导入 Easy Excel
  • idea一键打包docker镜像并推送远程harbor仓库的方法(包含spotify和fabric8两种方法)--全网唯一正确,秒杀99%水文
  • 前台页面从数据库中获取下拉框值
  • (SpringBoot)第七章:SpringBoot日志文件
  • 15分钟,不,用模板做数据可视化只需5分钟
  • Django模板层
  • GAT里面的sofamax函数的实现:
  • 2023.11.17 -hivesql调优,数据压缩,数据存储
  • 【图像分类】【深度学习】【Pytorch版本】ResNet模型算法详解
  • asp.net core mvc之 RAZOR共享指令和标签助手 TagHelpers
  • vivado产生报告阅读分析6-时序报告2
  • python+Django 使用apscheduler实现定时任务 管理调度
  • C#委托与事件
  • Azure 机器学习:使用 Azure 机器学习 CLI、SDK 和 REST API 训练模型
  • git 指定时间代码统计
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • docker python 配置
  • ES6核心特性
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • jdbc就是这么简单
  • Mocha测试初探
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • MySQL的数据类型
  • nginx 配置多 域名 + 多 https
  • php面试题 汇集2
  • Python打包系统简单入门
  • SpingCloudBus整合RabbitMQ
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 二维平面内的碰撞检测【一】
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 前端工程化(Gulp、Webpack)-webpack
  • 前端学习笔记之观察者模式
  • 无服务器化是企业 IT 架构的未来吗?
  • 一些关于Rust在2019年的思考
  • 移动端解决方案学习记录
  • postgresql行列转换函数
  • ​人工智能书单(数学基础篇)
  • $().each和$.each的区别
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (五)网络优化与超参数选择--九五小庞
  • (转)菜鸟学数据库(三)——存储过程
  • (转)母版页和相对路径
  • .gitignore文件---让git自动忽略指定文件
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net 调用php,php 调用.net com组件 --
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET连接数据库方式
  • .NET中的十进制浮点类型,徐汇区网站设计
  • @angular/cli项目构建--http(2)
  • @Responsebody与@RequestBody
  • @synthesize和@dynamic分别有什么作用?