简体   繁体   中英

Angular 2: How to bind Input to model property with getter and setter methods?

I'm making an Angular 2 web app. I have a model that is comprised of a few key properties, and then several other properties that are computed based off those key values.

All of my properties have getter methods. To keep my computed properties in sync with my key properties, the key properties are changed via setter methods which re-evaluate all of the computed properties. Here's a simplified example:

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

This keeps my model consistent: every time one of the key properties is changed, all of the computed properties are re-computed.

Now I need to figure out how to bind my properties to my component views. It seems like I can present the computed property getters using interpolation:

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

However, I'm not sure what the best way to bind my key properties to input fields would be. All of the examples of using two-way binding seem to use ngModel like this:

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

However, that seems geared towards binding to simple properties. I ideally need two-way binding using my separate getter and setter methods (getKeyValue and setKeyValue).

Is there any built-in way to accomplish this in Angular 2?

You need to use this longer form

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

You should be aware that the getXxx() methods will be called every time change detection runs, which can be quite often. Ensure that the getters return the same value (especially for objects the same instance) and ensure the getters don't have side effects, otherwise you'll get "Expression has changed since it was last checked ..." errors.

not sure what version of Angular is being used above, but the version I'm using (v4.3.5) allows binding directly to the getter/setter methods of a field using ngModel: in the typescript file:

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

and in the template file

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM