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

Angular 进阶之五: Signals到底用不用?

Angular 在V16的时候推出了Signals,在17正式作为主打功能之一强烈推荐,看过了各种博主的各种科普文章也没说明白,到底这东西值不值得用?毕竟项目大了,重构代码也不是闹着玩儿的。各种科普文章主要在说两点:

1. 用了性能提高

2. 用了方便,你改一个,使用的地方自动就获得通知。(听起来和Rxjs的Observer一样)

在Angular项目日常开发过程中主要的矛盾其实就两个。

1. Object的成员改了,不会触发子组件(component)的ngOnChange。需要手动调用detectChanges。

2. 性能,其中之一就是html template里头不能用function,不然会不停的调用。

这也是Signals可能可以解决的两个问题。我们用下面一个简单的例子来说明。

import { Component, signal, computed } from '@angular/core';interface Member {id: number;name: string;value: number;
}@Component({template: `<div><p>{{targetsSignal()[0].name}} has {{targetsSignal()[0].value}}</p><button (click)="increase()">Increase</button><button (click)="decrease()" [disabled]="canDecrease()">Decrease</button><p>Name starts with M</p><div *ngFor="let member of computedNames()">{{member.id}} - {{member.name}}</div><div style="height: 300px; width: 300px; background-color: #2f487e;" (mousemove)="onMousemove()"></div><test-signal-sub [members]="targetsSignal()"></test-signal-sub></div>`,selector: 'test-signal',
})export class SignalComponent {counter = 0;counter1 = 0;targets: Member[] = [{name: 'Maria', id: 1, value: 1}, {name: 'Michel', id: 2, value: 1}, {name: 'Jack', id: 3, value: 1}, {name: 'John', id: 4, value: 1}, {name: 'Sam', id: 5, value: 1}, {name: 'Mila', id: 6, value: 1}];readonly targetsSignal = signal<Member[]>(this.targets);computedNames = computed(() => {this.counter++console.log("namesFiltered() called! " + this.counter + " times!");return this.targetsSignal().filter(item => item.name.startsWith('M'));})constructor() {}onMousemove() {// console.log('Mouse moved');}increase() {const newTargets = [].concat(this.targetsSignal());newTargets[0].value += 1;this.targetsSignal.set(newTargets);}decrease() {this.targetsSignal.update(val => { val[0].value -= 1;return val;});}canDecrease() {this.counter1++;console.log("canDecrease() called! " + this.counter1 + " times!");return this.targetsSignal()[0].value <= 0;}
}
import { Component, OnChanges, SimpleChanges, Input } from '@angular/core';@Component({template: `<div><p>Sub signal component below:</p><p>{{name}} preferred {{color}}</p><p>{{members[0].name}} has value {{members[0].value}}</p></div>`,selector: 'test-signal-sub',
})export class SignalSubComponent implements OnChanges {@Input() members: any;color = '';name = '';readonly preferedColor = [{name: 'Maria', color: 'red'}, {name: 'Michel', color: 'blue'}, {name: 'Jack', color: 'yellow'}, {name: 'John', color: 'green'}, {name: 'Sam', color: 'black'}, {name: 'Mila', color: 'white'}];constructor() {}ngOnChanges(changes: SimpleChanges): void {if (changes.members?.previousValue !== changes.members?.currentValue) {const index = changes.members?.currentValue[0].value % changes.members?.currentValue.length ?? 0;this.color = this.preferedColor[index].color;this.name = this.preferedColor[index].name;}}
}

两个组件,父组件的html template里绑定了computedNames,和canDecrease,从外表也看不出来区别,但是如果使用鼠标在蓝色区域晃动,控制台就会打印canDecrease被不停调用,computedNames没事,这个例子说明了Signal可以被用在html template里,解决的主要场景之一就是button的状态,现实中不都是理想情况,button属于form,一个valid状态就解决了button是不是disable。很多情况button的[disabled]后面跟了一串判断,"a || b || !c || d"等等,现在有了signal就直接一个signal就好了。但是重构时需要把涉及到的a,b,c,d这些成员都改成signal。这就可能需要一次重构一整个component。

在上面例子中increase使用set每次用新数组更新signal,decrease使用update,每次只改原来的数组,在子组件中,会看到,increase会触发子组件的ngOnChange,但是decrease不会。这就和原来没什么区别了。还是Angular的老问题,对象引用不变,成员变,无法触发子组件的ngOnChange。

所以,Signals也没有宣传中吹的天花乱坠那么厉害,解决的问题有限,它更像是一个Rxjs的一个封装,一个别名,一个简化版本。是不是要重构代码就看大家自己的需求了。

PS:Angular在开发signal component和双向绑定的signal,都在他们的任务列表中,等这两个发布可能会带来更多的好处,

相关文章:

Angular 进阶之五: Signals到底用不用?

Angular 在V16的时候推出了Signals&#xff0c;在17正式作为主打功能之一强烈推荐&#xff0c;看过了各种博主的各种科普文章也没说明白&#xff0c;到底这东西值不值得用&#xff1f;毕竟项目大了&#xff0c;重构代码也不是闹着玩儿的。各种科普文章主要在说两点&#xff1a;…...

构建数字化金融生态系统:云原生的创新方法

内容来自演讲&#xff1a;曾祥龙 | DaoCloud | 解决方案架构师 摘要 本文探讨了金融企业在实施云原生体系时面临的挑战&#xff0c;包括复杂性、安全、数据持久化、服务网格使用和高可用容灾架构等。针对网络管理复杂性&#xff0c;文章提出了Spiderpool开源项目&#xff0c;…...

前端性能优化五:css和js位置

1. 精简HTML代码: ①. css链接文件尽量放在页面头部:a. css的加载不会阻塞DOM Tree的解析.b. 但会阻塞DOM Tree渲染,也会阻塞后面JS的执行.c. 将css放在任何body元素之前:(1). 可以确保在文档中解析了所有css的样式包括内联样式和外联的.(2). 减少了浏览器必须重排文档的次数.…...

苏州耕耘无忧物联网:降本增效,设备维护管理数字化转型的引领者

随着科技的快速发展和工业4.0的推动&#xff0c;设备维护管理已经从传统的被动式、经验式维护&#xff0c;转向了更加积极主动、数据驱动的维护模式。在这个过程中&#xff0c;苏州耕耘无忧物联科技有限公司以其深厚的技术积累和丰富的管理经验&#xff0c;引领着设备维护管理数…...

15个热门的开源数据可视化项目

数据可视化(即 BI仪表盘)是图形表示的数据。它涉及产生将表示的数据之间的关系传达给图像查看者的图像。这种通信是通过在可视化过程中使用图形标记和数据值之间的系统映射来实现的。该映射建立了如何在视觉上表示数据值,确定图形标记的属性(例如大小或颜色)如何以及在多大程…...

【第七在线】数据分析与人工智能在商品计划中的应用

随着技术的不断进步&#xff0c;数据分析和人工智能&#xff08;AI&#xff09;已经成为了现代商品计划的关键组成部分。在服装行业&#xff0c;这两项技术正在帮助企业更好地理解市场需求、优化库存管理、提高生产效率和提供更好的客户体验。本文将深入探讨数据分析和人工智能…...

【圣诞】极安云科赠书活动第①期:CTF实战:从入门到提升

【圣诞】极安云科赠书活动第①期&#xff1a;CTF实战:从入门到提升 9787111724834 9787121376955 9787302556275 ISBN编号&#xff1a;9787111724834 书名&#xff1a;CTF实战:从入门到提升 定&#xff1a;99.00元 开本&#xff1a;184&#xff4d;&#xff4d;260&#xff…...

分布式搜索elasticsearch概念

什么是elasticsearch&#xff1f; elasticsearch是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 目录 elasticsearch的场景 elasticsearch的发展 Lucene篇 Elasticsearch篇 elasticsearch的安装 elasticsearch的场景 elasticsear…...

Linux环境安装Hadoop

&#xff08;1&#xff09;下载Hadoop安装包并上传 下载Hadoop安装包到本地&#xff0c;并导入到Linux服务器的/opt/software路径下 &#xff08;2&#xff09;解压安装包 解压安装文件并放到/opt/module下面 [roothadoop100 ~]$ cd /opt/software [roothadoop100 software…...

swing快速入门(二十五)

注释很详细&#xff0c;直接上代码 新增内容 1.ImageIO.write读取并显示图片 2.ImageIO.writeImageIO.write读取并保存图片 package swing21_30;import javax.imageio.ImageIO; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent…...

智能优化算法应用:基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.卷尾猴算法4.实验参数设定5.算法结果6.参考文…...

前端传输formDate格式的数据,后端不能用@RequestBody接收

写了个接口&#xff0c;跟前端对接&#xff0c;前端说怎么一直415的报错 我寻思不对啊&#xff0c;我swagger都请求成功了&#xff0c;后来发现前端一直是以formdata格式提交的数据&#xff0c;这样我其实是可以不加RequestBody的&#xff1b; 知识点&#xff1a; RequestBody…...

【AivaAI】做音乐,无人能比它更专业

关于Aiva Aiva AIVA是音乐制作初创公司AIVA Technologies打造的一款人工智能产品。是人工智能领域头款获得国际认证的虚拟作曲家。 Aiva登录 可以选择Google登录&#xff0c;或者其他邮箱登录。 输入用户名&#xff0c;登录完成。 开始制作音乐 在主页选择“创建曲目…...

嵌入式开发网络配置——windows连热点,开发板和电脑网线直连

目录 电脑 WiFi 上网&#xff0c;开发板和电脑直连 使用场景 设置VMware虚拟机的网络配置 Ubuntu设置——版本18.04 ​编辑 windows设置 开发板设置 原因&#xff1a;虚拟机Linux移植可执行程序到开发板失败 最后发现虚拟机的Linuxping不通开发板 下面是我的解决方法 …...

基于Netty构建Websocket服务端

除了构建TCP和UDP服务器和客户端&#xff0c;Netty还可以用于构建WebSocket服务器。WebSocket是一种基于TCP协议的双向通信协议&#xff0c;可以在Web浏览器和Web服务器之间建立实时通信通道。下面是一个简单的示例&#xff0c;演示如何使用Netty构建一个WebSocket服务器。 项目…...

基于Rocket MQ扩展的无限延迟消息队列

基于Rocket MQ扩展的无限延迟消息队列 背景: Rocket MQ支持的延迟队列时间是固定间隔的, 默认19个等级(包含0等级): 0s, 1s, 5s, 10s, 30s, 1m, 2m, 3m, 4m, 5m, 6m, 7m, 8m, 9m, 10m, 20m, 30m, 1h. 我们的需求是实现用户下单后48小时或72小时给用户发送逼单邮件. 使用默认的…...

Python办公自动化 – 日志分析和自动化FTP操作

Python办公自动化 – 日志分析和自动化FTP操作 以下是往期的文章目录&#xff0c;需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自动化 – 对…...

MyBatis 关联查询

目录 一、一对一查询&#xff08;sqlMapper配置文件&#xff09; 1、需求&#xff1a; 2、创建account和user实体类 3、创建AccountMapper 接口 4、创建并配置AccountMapper.xml 5、测试 二、一对多查询&#xff08;sqlMapper配置文件&#xff09; 1、需求&#xff1a;…...

NVIDIA NCCL 源码学习(十二)- double binary tree

上节我们以ring allreduce为例看到了集合通信的过程&#xff0c;但是随着训练任务中使用的gpu个数的扩展&#xff0c;ring allreduce的延迟会线性增长&#xff0c;为了解决这个问题&#xff0c;NCCL引入了tree算法&#xff0c;即double binary tree。 double binary tree 朴素…...

.net core webapi 大文件上传到wwwroot文件夹

1.配置staticfiles(program文件中) app.UseStaticFiles();2.在wwwroot下创建upload文件夹 3.返回结果封装 namespace webapi;/// <summary> /// 统一数据响应格式 /// </summary> public class Results<T> {/// <summary>/// 自定义的响应码&#xff…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...