Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Aurelia's bindable decorator on a property with getter and setter

I have no problem using the @bindable decorator for a property on a class. E.g.

export class SomeClass {
    @bindable public SomeProperty: Date = new Date();
}

But I'm stumped when it comes to using it with properties that have a getter/setter implementation. E.g.

export class SomeClass2 {
    // Where should the @bindable go now?
    private _someProperty: Date = new Date();

    public get SomeProperty(): Date {
        return this._someProperty;
    }

    public set SomeProperty(value: Date) {
        // Do some manipulation / validation here
        this._someProperty = value;
    }
}

I'm sure I'm missing something simple here...

like image 212
Jaans Avatar asked Jan 06 '23 09:01

Jaans


1 Answers

Bindable works by adding a getter and a setter on your property that it uses for observing changes. It's recommended that you utilize the ${propertyName}Changed(newValue, oldValue) callback method to accomplish what you're trying to do. Here is an ES2016 example:

ViewModel

import {bindable} from 'aurelia-framework';

export class MyCustomElement {
  @bindable name;

  _name;
  errorMessage = '';

  nameChanged(newValue) {
    if(newValue.length >= 5 ) {
      this.errorMessage = 'Name is too long';
    }
    else {
      this._name = newValue;
      this.errorMessage = '';
    }
  }
}

View

<template>
  <p>Name is: ${_name}</p>
  <p>Error is: ${errorMessage}</p>
</template>

Note that since ES2016 doesn't have private variables, I'm able to use the private backing field in my View. I'm not sure if you can do this in TypeScript, but if you can't, do note that changing the value of the name property in your code will also trigger the nameChanged callback to fire. So you would need to check if newValue is equal to this._name and ignore it in that case.

like image 108
PW Kad Avatar answered Jan 23 '23 03:01

PW Kad