marekpw
marekpw

Reputation: 712

Aurelia event aggregator VS getter method for two-way data binding

I'm new to Aurelia and learning about how to use two-way data binding correctly.

The application I'm working on right now will be composed of multiple sub-apps, each with their own sidebar links (menu) and stuff. The applications can be changed easily at any time using a switcher or the dashboard.

I've noticed that I can't bind an if to a method on the model, as the method doesn't get called periodically:

export class App {
    public getMenu() {
        return this.someService.currentApp !== null
            ? this.someService.currentApp.menu
            : [];
    }
}
<div if.bind="getMenu().length > 0"></div>

The code there is pretty long, so putting it in the template doesn't make sense.

However, if I switch this code to a TS getter instead, everything works great:

export class App {
    get menu() {
        return this.someService.currentApp !== null
            ? this.someService.currentApp.menu
            : [];
    }
}
<div if.bind="menu.length > 0"></div>

However, before I noticed this works, I also tried using the Event Aggregator. I fire an event when the app is changed and subscribe to it on the App ViewModel:

export class App {
    public menu: AppMenuLink[];

    public constructor(ea: EventAggregator) {
        ea.subscribe('app:changed', (response) => {
            this.menu = response.app !== null ? response.app.menu : [];
        });
    }
}
<div if.bind="menu.length > 0"></div>

This method works too (obviously), but I feel like it could make my code too bloated with event subscribers if I abuse it too much in the long run.

So, my question is: Which method is better (and why), or am I missing something completely and doing this all wrong? I'd like to get this clarified before my codebase gets big.

Also (this probably should be another question), while I'm at using the event aggregator, is there a way to let the template know what data to display (when it changes on the event callback), rather than have it check if it changed? I'm thinking this could stop useless checks done by Aurelia to see if the property has changed.

Upvotes: 1

Views: 298

Answers (1)

Ashley Grant
Ashley Grant

Reputation: 10887

Why not create a getter and use the computedFrom decorator to avoid dirty checking?

@computedFrom('someService.currentApp.menu.length')
get menuLength() {
  return this.someService.currentApp !== null
    ? this.someService.currentApp.menu.length
    : 0;
}

You'd have to test this to see if it works. If it does, awesome! If not, let me know and I'll give some other options.

Upvotes: 4

Related Questions