【问题标题】:Angular 2: How to bind Input to model property with getter and setter methods?Angular 2:如何使用 getter 和 setter 方法将输入绑定到模型属性?
【发布时间】:2017-03-13 12:06:53
【问题描述】:

我正在制作一个 Angular 2 网络应用程序。我有一个模型,它由几个关键属性组成,然后是根据这些关键值计算的其他几个属性。

我所有的属性都有 getter 方法。为了使我的计算属性与我的关键属性保持同步,关键属性通过重新评估所有计算属性的 setter 方法进行更改。这是一个简化的示例:

export class Model{
    private _keyValue: number;
    private _computedValue: number;

    getKeyValue(): number{
        return this._keyValue;
    }

    setKeyValue(value: number){
        this._keyValue = value;
        this.evaluateComputedValues(); // This might be time-consuming
    }

    getComputedValue(): number{
        return this._computedValue;
    }
}

这使我的模型保持一致:每次更改一个关键属性时,都会重新计算所有计算的属性。

现在我需要弄清楚如何将我的属性绑定到我的组件视图。看来我可以使用插值来呈现计算属性 getter:

<div>{{model.getComputedValue()}}</div>

但是,我不确定将我的关键属性绑定到输入字段的最佳方式是什么。所有使用双向绑定的示例似乎都像这样使用 ngModel:

<input [(ngModel)]='model.property'>

但是,这似乎是为了绑定到简单的属性。理想情况下,我需要使用单独的 getter 和 setter 方法(getKeyValue 和 setKeyValue)进行双向绑定。

在 Angular 2 中是否有任何内置方法可以实现这一点?

【问题讨论】:

  • 为什么不使用 TypeScript 的 getter 和 setter 而不是函数?您可以获得相同的功能,但可以像使用字段一样使用它们。另见stackoverflow.com/questions/12827266/get-and-set-in-typescript
  • @Günter Zöchbauer 如果我走那条路,会像这样 [(ngModel)]='keyValue()' 那样绑定属性吗? Angular 2 会弄清楚何时使用 getter 和 setter?
  • 差不多。它看起来像[(ngModel)]='keyValue'。对于这样的 getter/setter,您不需要 ()

标签: angular typescript


【解决方案1】:

你需要使用这个更长的形式

<input [ngModel]='model.getProperty()' (ngModelChange)="model.setProperty($event)">

您应该知道,每次更改检测运行时都会调用 getXxx() 方法,这可能非常频繁。确保 getter 返回相同的值(尤其是对于相同实例的对象)并确保 getter 没有副作用,否则您将收到“Expression has changed since it was last checked ...”错误。

【讨论】:

  • 我很好奇,正如你所说,每次更改检测运行时都会调用 get 方法。这也适用于使用打字稿吸气剂,不是吗?它会对性能产生巨大影响吗?我猜不是,如果你真的只是返回值或者只做小处理,对吧?
  • 如果该方法不能做实际(昂贵的)工作,那还不错。如果 getter/方法返回像 return { x: y }; 这样的对象,则很容易出错,因为这样会返回一个不同的对象实例,这会破坏更改检测。
  • 没错,正如您所说,必须小心。因此,我可以理解为什么不鼓励它。但另一方面,例如在处理笨拙的 REST API 时,getter 和 setter 是可行的方法,因为您可能会在一个地方进行一些转换,即模型,而不是使用此模型的所有组件。
  • 如果您进行转换,您应该考虑使用管道。对于 asyn 结果绑定到 observables isimg | async 否则将结果分配给一个字段并绑定到该字段。 getter tjat 实际上做了一些应该避免的工作。
  • 问题,你不可能使用[(ngModel)]='someValue,对吧?因为这意味着您必须提供一个 Change 函数,但我不知道如何命名该 change 函数,以便在输入更改时调用它。默认不会是ngModelChange,对吧?我正在查看https://angular.io/guide/template-syntax#two-way-binding--- 的示例,但这不使用 ngModel 的输入。
【解决方案2】:

不确定上面使用的是哪个版本的 Angular,但我使用的版本 (v4.3.5) 允许使用 ngModel 直接绑定到字段的 getter/setter 方法: 在打字稿文件中:

  get AnnualRevenueFormatted():string{
    return  this.AnnualRevenue !== undefined ?  `$${this.AnnualRevenue.toLocaleString()}`: '$0';
  }

  // strip out all the currency information and apply to Annual Revenue
  set AnnualRevenueFormatted(val: string) {
    const revenueVal = val.replace(/[^\d]/g, '');
    this.AnnualRevenue = parseInt(revenueVal);
  }

在模板文件中

<input type="text" class="text-input" [(ngModel)]="accountInfo.AnnualRevenueFormatted"  />

【讨论】:

    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多