首页 > 解决方案 > 在模板上显示模型计算数据的角度正确方法

问题描述

考虑一个Person模型,例如:

class Person {
  firstName: string;
  lastName: string;
}

以及从中计算/派生的数据,例如(fullName`${firstName} ${lastName}`只是一个示例,因为计算可能更复杂和繁重)。

在组件模板上显示计算数据的正确方法是什么?考虑到:

我考虑过对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也适用于firstNamelastName确保不变性模式,但这样我就不能Person在另一个模板上下文中使用模型,例如,我需要绑定firstNamelastName一些输入模型。

我真的很想知道正确处理这种常见情况的标准/正确/最佳实践方法是什么。

标签: javascriptangulartypescript

解决方案


我会考虑使用属性(获取)


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}`;
  }

}

推荐阅读