在 Angular 17.1 中,我们引入了基于 Signal 的 Inputs,作为基于装饰器的 @Input()
的响应式替代方案。
新的 Signal Inputs 为开发人员提供了新的方法:
OnPush
和未来的 Zoneless 更流畅的体验。这些可在开发者预览版中使用,我们希望获得您的反馈!
与 @Input
一样,Signal Inputs 允许从父组件绑定值。与 Signal Inputs 的一个关键区别是,这些值使用 Signal 公开,并且可以在组件的生命周期中更改。
现在,开发人员可以利用 Signals 的力量以反应方式有效地响应这些潜在的变化。 Angular 支持两种 Signal Inputs 变体。
input.required
函数声明。每当您使用 input
或 input.required
函数作为类成员的初始值设定项时,Angular 都会自动识别 Inputs。下面演示了如何在应用程序中声明 Signal Inputs:
import { Component, input } from '@angular/core';
@Component({…})
export class MyComp {
// optional inputs
firstName = input<string>();
age = input(0);
// required inputs
lastName = input.required<string>();
}
定义它们后,您可以在模板中使用它们,其语法与其他 Signals 相同:
<p>First name: {{ firstName() }}</p>
<p>Last name: {{ lastName() }}</p>
请参阅Signal Inputs专用指南了解更多信息。 https://angular.io/guide/signal-inputs 。
与基于装饰器的 @Input
相比,Signal Inputs 提供了许多好处:
OnPush
组件标记为脏(dirty)。
computed
轻松地派生值,就像其他 Signals 一样。effect
而不是 ngOnChanges
或 setters,更轻松、更本地地监视 Inputs。Angular 团队建议,一旦 Signal Inputs 脱离开发者预览并在即将推出的版本中升级为生产就绪,就使用 Signal Inputs。
Signals 提供了强大的反应性模型,使您能够有效地监视更改、派生值,同时在应用程序的特定部分需要重新渲染时自动通知 Angular。
这使得构建仅刷新实际更改的部分的高性能应用程序变得更加容易和安全。
下面我们重点介绍一些潜在的用例。
声明与渲染
此示例演示如何声明组件的 Signal Inputs 并显示其值。
import { Component, input } from '@angular/core';
@Component({
// …
template: `Your name is: {{ yourName() }}`,
})
class HelloComponent {
yourName = input.required<string>();
}
观察变化
此示例监视 firstName
Input 的更改,并使用 effect()
对这些更改做出反应:
import { input, effect } from '@angular/core';
class MyComp {
firstName = input.required<string>();
constructor() {
effect(() => {
// will be called when `firstName` is initialized or changes.
console.log(this.firstName());
});
}
}
派生值
您可以使用 computed
根据 Signal Inputs 有效地派生值。Signal Inputs 可以像应用程序中的任何其他 Signals 一样在 computed
中使用。
在以下示例中,我们从名为 age
的 Input 中派生一个值。每当 age
发生变化时, ageMultiplied
字段都会收到通知,并且可以重新运行以将年龄乘以 2。另一方面,如果 age
没有改变,则 ageMultiplied
推导将有效地使用先前存储的值而不执行。
import {Component, input, computed} from '@angular/core';
@Component({…})
export class MyComp {
age = input(0);
// age multiplied by two.
ageMultiplied = computed(() => this.age() * 2);
}
值转换
Signal Inputs 支持与基于装饰器的 Inputs 相同的功能。您可以为 Signal Inputs 指定转换函数,以将原始值解析为您期望的 Inputs 类型。
请注意,值转换永远不应该改变 Inputs 的含义。有关这方面的更多信息,请参阅 angular.dev 的新指南 — https://angular.io/guide/signal-inputs#value-transforms
export class MyCheckboxComponent {
disabled = input(false, {
// supports `<my-checkbox disabled="" />` as a shorthand
transform: (v: boolean|string) => typeof v === 'string' ? v === '' : v,
});
}
别名
您还可以做一些事情,例如为 Inputs 添加别名以满足您的需求:
export class StudentDirective {
age = input(0, { alias: 'studentAge' });
}
仅仅是开始
我们非常高兴能够在开发者预览版中将此功能引入 Angular 社区。Signal Inputs 现在即可使用,并且已做好生产准备。开发者预览版允许我们根据从社区收到的反馈进行更改。
考虑到这一点,在我们继续稳定 Signal Inputs 的过程中,我们希望得到您的反馈。对于即将推出的 API,存在一些复杂的权衡和其他问题:
input<string>()
的简写可能会令人困惑,因为 Inputs 隐式使用 undefined
作为初始值。
string
?undefined
作为 Google 代码库中的初始值。model()
并向消费者公开组件的更新状态。为什么这对你不起作用?您的反馈很有价值,我们期待您的来信。如果您有反馈意见,请考虑在 GitHub 或 X 上的评论中告知我们。
请务必立即使用 ng update
安装最新版本的 Angular 来尝试 Signal Inputs。
谢谢并让我们了解最新情况!
原文链接:https://blog.angular.dev/signal-inputs-available-in-developer-preview-6a7ff1941823
翻译链接:https://zhuanlan.zhihu.com/p/684098176