Search code examples
typescriptaurelia

Update Aurelia binding when properties change


I'm using Aurelia with TypeScript. I'm trying to bind an object to the view and I want the view to update when I change a property of my object. I know that Aurelia only watches the object and some array manipulations (push, splice etc). I also know that there are some binding helpers such as @computedFrom and using the BindingEngine but I still can't find the best approach when using value converters.

In my example I have class in TypeScript, e.g. "class Car". Then I bind multiple car objects to the view, e.g. ${car1}, ${car2} etc. I add a value converter to present the car, e.g. ${car1 | carPresenter}. This displays the information like this: "A blue car with full tank and three passengers". If I change a car property, e.g. "car1.passengers++" then I want the ${car1 | carPresenter} to update.

Maybe a value converter is the wrong approach? Please advise on better methods if that's the case. I want to present complex objects by showing some of it's properties but not necessarily all of them. And those presentations should update when the underlying properties change.

I have created a gist with a simplified example that illustrates the problem: https://gist.run/?id=06287de5eb179b32fa0b134eb59ebc68


Solution

  • There is an additional binding decorator you can leverage: @observable [related docs].

    More info: Working With Aurelia @observable (Dwayne's blog is an extremely useful resource for learning Aurelia).

    Gist demo: https://gist.run/?id=c359860951717457e630e3fde1a4d6aa

    In this demo, the Car object has its own class defined, where all necessary properties have an @observable decorator. Value converter has been replaced by description getter method.

    Car class

    import { observable } from 'aurelia-framework';
    
    export class Car {
        @observable
        color;
    
        @observable
        gasLevel;
    
        @observable
        passengers;
    
        constructor(data) {
            // ...
        }
    
        get description() {
            return `A ${this.color} car with ${this.gasLevel} tank and ${this.passengers} passengers`;
        }
    }