角度信号 - 有什么优势?

Ka *_*ech 4 signals angular angular-signals

我试图了解使用 Angular Signals 的优势。许多解释中都给出了一个计数示例,但我试图理解的是,以这种方式使用信号的优点与我在下面通过变量 myCount 和 myCountDouble 所做的方式相反?

\n

https://stackblitz.com/edit/angular-qtd3ku?file=src/main.ts

\n

这是我的代码+ stackblitz

\n
import \'zone.js/dist/zone\';\nimport { Component } from \'@angular/core\';\nimport { bootstrapApplication } from \'@angular/platform-browser\';\nimport { signal } from \'./signals/signal\';\nimport { computed } from \'./signals/computed\';\nimport { effect } from \'./signals/effect\';\nimport { TestArraysCmp } from \'./testing-arrays.component\';\nimport { TestObjectsCmp } from \'./testing-objects.component\';\n\n/*\n  \xe2\x9a\xa0\xef\xb8\x8f Please keep in mind that this is only the signals implementation. We still depend on zone and current CD strategy to propagate change in the template which might not be the case when Angular releases signals officially!\n*/\n\n// Signals are primitives, so we can use them outside the component class\nconst myValue = signal(10000);\n\neffect(() => {\n  console.log(\'MyValue changed\', myValue());\n});\n\n// Uncomment this\n// setInterval(() => {\n//   myValue.update((s) => s - 1);\n// }, 1000);\n\n@Component({\n  selector: \'my-app\',\n  standalone: true,\n  template: `\n    <div>Count: {{ count() }}</div>\n    <div>Double: {{ double() }}</div>\n    <div>MyCount: {{myCount}}</div>\n    <div>MyDoubleCount: {{myCountDouble}}</div>\n    <button (click)="inc()">Increase</button>\n    <button (click)="reset()">Reset</button>\n\n    <br>\n    <!-- <test-arrays /> -->\n    <!-- <test-objects /> -->\n\n  `,\n  imports: [TestArraysCmp, TestObjectsCmp],\n})\nexport class App {\n  myCount: number = 0;\n  myCountDouble: number = 0;\n  myCountType: string;\n\n  count = signal(0);\n\n  double = computed(() => this.count() * 2);\n\n  countType = computed(() => (this.count() % 2 === 0 ? \'even\' : \'odd\'));\n\n  constructor() {\n    effect(() => {\n      console.log(\'Count changed\', this.count());\n      console.log(this.count(), \'is\', this.countType());\n    });\n  }\n\n  inc() {\n    this.count.update((c) => c + 1);\n    this.myCount = this.myCount + 1;\n    this.myCountDouble = this.myCount * 2;\n    this.myCountType = this.myCount % 2 === 0 ? \'even\' : \'odd\';\n    console.log(\'Old Way\', this.myCount, \'is\', this.myCountType);\n  }\n  reset() {\n    this.count.set(0);\n    this.myCount = 0;\n    this.myCountDouble = 0;\n    this.myCountType = \'\';\n  }\n}\n\nbootstrapApplication(App);\n
Run Code Online (Sandbox Code Playgroud)\n

lic*_*dom 5

其优势主要与 Angular 处理变化检测的方式有关。

使用 Zone.js,当您触发 inc() 方法时,Angular 将查找整个组件树以查找更改,即使只有一件事发生了更改。

通过信号,我们明确指出表明只有特定的事物发生了变化并且需要更新。

由于更新计数器是一个同步操作 - 我们不需要等待 API 响应,我们知道该值,因此我们可以使用它立即更新计数器 - 使用信号会执行得更好,因为它向 Angular 指示确切地说,只有依赖于该信号的元素才应该被更新,从而消除了对整个组件树进行脏检查的需要。

  • React 使用虚拟 DOM 来模仿真实的 DOM。从那里,它根据状态获取 DOM 的快照,并通过这些快照的比较(或协调),然后决定哪些部分需要更新(在真实的 DOM 中)。它看起来更像是信号,作为一个反应原语,将为 Angular 带来我们可以在 Solidjs 中找到的反应范式 - 通过仅更新 DOM 中与特定数据更改直接相关的部分 (2认同)