Angular 2:如何使用getter和setter方法将Input属性绑定到model属性?

MWi*_*ead 17 typescript angular

我正在制作一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

<div>{{model.getComputedValue()}}</div>
Run Code Online (Sandbox Code Playgroud)

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

<input [(ngModel)]='model.property'>
Run Code Online (Sandbox Code Playgroud)

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

在Angular 2中有没有内置的方法来实现这一点?

Gün*_*uer 24

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

<input [ngModel]='model.getProperty()' (ngModelChange)="model.setProperty($event)">
Run Code Online (Sandbox Code Playgroud)

您应该知道每次更改检测运行时都会调用getXxx()方法,这可能经常发生.确保getter返回相同的值(特别是对于同一实例的对象)并确保getter没有副作用,否则你会得到"表达式自上次检查后已经更改..."错误.

  • 如果该方法没有完成实际(昂贵)的工作,那也不算太糟糕。如果 getter/方法返回像“return { x: y };”这样的对象,则很容易出错,因为这样会返回一个不同的对象实例,从而破坏更改检测。 (2认同)

Dar*_*976 5

不知道上面使用的是哪个版本的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);
  }
Run Code Online (Sandbox Code Playgroud)

并在模板文件中

<input type="text" class="text-input" [(ngModel)]="accountInfo.AnnualRevenueFormatted"  />
Run Code Online (Sandbox Code Playgroud)