javascript - 在模板上显示模型计算数据的角度正确方法
问题描述
考虑一个Person
模型,例如:
class Person {
firstName: string;
lastName: string;
}
以及从中计算/派生的数据,例如(fullName
这`${firstName} ${lastName}`
只是一个示例,因为计算可能更复杂和繁重)。
在组件模板上显示计算数据的正确方法是什么?考虑到:
- 我想尽可能尊重 DRY,我不想复制我的模型或在模板上写很多次
{{ person.firstName }} {{ person.lastName }}
; - 由于性能问题,即使使用
OnPush
更改检测策略,在模板上使用 getter 或方法也不可行; - 计算逻辑必须留在模型中,因为我需要在TS代码的某个地方使用它,所以我不想使用纯管道,或者建议的组件计算属性(如果在某些时候会实现)或一些解决方法获得类似的行为。
我考虑过对Person
模型使用不可变的方法,并仅在构造函数中计算派生属性:
class Person {
firstName: string;
lastName: string;
readonly fullName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
this.fullName = `${firstName} ${lastName}`;
}
}
显然,使用这种方法我不能person.firstName = 'Changed'
同时更新fullName
属性,但我必须这样做person = new Person('Changed', person.lastName)
。
我考虑过readonly
也适用于firstName
并lastName
确保不变性模式,但这样我就不能Person
在另一个模板上下文中使用模型,例如,我需要绑定firstName
和lastName
一些输入模型。
我真的很想知道正确处理这种常见情况的标准/正确/最佳实践方法是什么。
解决方案
我会考虑使用属性(获取)
class Person {
firstName: string;
lastName: string;
get fullName(): string { return `${this.firstName} ${this.lastName}`;}
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
}
编辑
要针对经常发生的更改进行优化并减少重新计算,您可以使用 Subject 并使用 debounceTime 对其进行管道传输。
class Person{
private _firstName: string;
private _lastName: string;
private _fullName: string;
private _debounceFirstname = new Subject<string>();
private _debounceLastname = new Subject<string>();
constructor(firstName: string, lastName: string) {
this._firstName = firstName;
this._lastName = lastName;
this._debounceFirstname
.pipe(debounceTime(300)).subscribe((value: string) => this.firstName = value);
this._debounceLastname
.pipe(debounceTime(300)).subscribe((value: string) => this.lastName = value);
this.changeCalculation();
}
get firstName(): string {
return this._firstName;
}
set firstName(value: string) {
this._firstName = value;
this.changeCalculation();
}
get lastName(): string {
return this._lastName;
}
set lastName(value: string) {
this._lastName = value;
this.changeCalculation();
}
get fullName(): string{
return this._fullName;
}
private changeCalculation(): void {
this._fullName= `${this.firstName} ${this.lastName}`;
}
}
推荐阅读
- javascript - 如何阻止 v-hover 在 Vuetify 中触发我的函数
- reactjs - 在反应本机的持有模式上显示模式
- javascript - 添加到数据库时使用 AJAX 防止刷新
- javascript - 在从 observable 接收到特定消息后停止接收消息
- database - 人为创建 Cassandra 错误以测试重试策略
- c++ - 带有“-”前缀的命令行参数
- r - 带有 ggplot() 函数的条形图在 R-studio 中不起作用
- java - ListView CustomAdapter 位置卡在 0
- django - 使用 slug 动态更改页面并在模板中包含标签
- php - 预订系统ala airbnb 多对多laravel 关系?