专业建站公司联系方式,凡科网站自己如何做,外贸网站wordpress加ssl,深圳鲜花团购网站建设Angular 在V16的时候推出了Signals#xff0c;在17正式作为主打功能之一强烈推荐#xff0c;看过了各种博主的各种科普文章也没说明白#xff0c;到底这东西值不值得用#xff1f;毕竟项目大了#xff0c;重构代码也不是闹着玩儿的。各种科普文章主要在说两点#xff1a;…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: divp{{targetsSignal()[0].name}} has {{targetsSignal()[0].value}}/pbutton (click)increase()Increase/buttonbutton (click)decrease() [disabled]canDecrease()Decrease/buttonpName starts with M/pdiv *ngForlet member of computedNames(){{member.id}} - {{member.name}}/divdiv styleheight: 300px; width: 300px; background-color: #2f487e; (mousemove)onMousemove()/divtest-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 signalMember[](this.targets);computedNames computed(() {this.counterconsole.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: divpSub signal component below:/pp{{name}} preferred {{color}}/pp{{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每次用新数组更新signaldecrease使用update每次只改原来的数组在子组件中会看到increase会触发子组件的ngOnChange但是decrease不会。这就和原来没什么区别了。还是Angular的老问题对象引用不变成员变无法触发子组件的ngOnChange。 所以Signals也没有宣传中吹的天花乱坠那么厉害解决的问题有限它更像是一个Rxjs的一个封装一个别名一个简化版本。是不是要重构代码就看大家自己的需求了。
PSAngular在开发signal component和双向绑定的signal都在他们的任务列表中等这两个发布可能会带来更多的好处