Angular:Setters 与 ngOnChanges - 哪一个更好?
这篇文章最初发表于Angular Bites
获取有关 Angular 组件属性变化的通知通常通过两种方式完成:
- 向属性添加一个 setter
- 使用
ngOnChanges
生命周期钩子
但是...有最佳实践吗?
最近,我和同事们在尝试在代码库中建立标准实践时,进行了一次讨论。我们试图找到客观的论据来了解哪种方法更好。
像往常一样,答案取决于具体情况。
风格
风格本身就是一个非常主观的因素,但使用 setter 无疑是我最喜欢的方法。我们来看一个常见的场景:
class MyComponent {
private subject$ = new Subject<string>();
@Input()
set name(name: string) {
this.subject$.next(name);
}
}
它简洁、类型安全,并且鼓励使用 Observable。个人认为没什么可不喜欢的。
但是你不能添加 getter 吗?
是的。事实证明,Angular 不会通过调用属性的 getter 来检查先前的值,而是将其值存储在组件的逻辑视图中。
如果您有兴趣阅读发生这种情况的源代码,请查看此处。
class MyComponent implements OnChanges {
@Input() name: string;
private subject$ = new Subject<string>();
ngOnChanges(changes: SimpleChanges) {
// changes.name.currentValue is typed as `any`
this.subject$.next(changes.name.currentValue);
}
}
ngOnChanges
相反,生命周期钩子并不那么好(在我看来)——最重要的是,它是弱类型的。
另外 - 值得一提的是,使用 setter 通常需要更少的代码,这始终是一件好事。
表现
性能变化大吗?起初,我们认为将其ngOnChanges
作为 Angular 生命周期钩子的一部分会更高效,这样就能感知到属性何时发生变化。
但事实证明,只有当绑定为新实例时,Angular 才会更改属性。当然,我们考虑到了变更检测OnPush
。
从性能角度来看,根据我的测试,没有更好的方法,而且在决定采用哪种方法时也不应该将其作为一个因素。
处理多个输入
当考虑到多个输入的变化时,情况会发生变化:
class MyComponent implements OnChanges {
@Input() name: string;
@Input() email: string;
private username$ = new Subject<string>();
ngOnChanges({ name, email }: SimpleChanges) {
const username = name.currentValue || email.currentValue;
this.username$.next(username);
}
}
在这种情况下,一次性接收所有输入相当直接和简单。
但由于这种情况并不常见,有时是代码异味的标志,您会发现自己大多数时候都想使用 setter。
最后,请记住,这个决定始终取决于您和您的团队的偏好。
希望你喜欢这篇文章。再见!
鏂囩珷鏉ユ簮锛�https://dev.to/angular/angular-setters-vs-ngonchanges-which-one-is-better-4f2b