Introducing aurelia-computed

aurelia-computed

aurelia-computed is a plugin for the Aurelia platform that improves the efficiency of data-binding computed properties. Binding to computed properties (properties with getter functions) typically requires dirty-checking. This plugin uses Aurelia's javascript parser to parse the body of the property's getter function and check the resulting abstract syntax tree (AST) for "observability". If the getter function is observable, a specialized observer is returned to Aurelia's pluggable binding system. The observer publishes change events when properties accessed by the getter function change.

What types of properties can aurelia-computed observe?

One-liners that access members that are accessible from the binding scope are good candidates for observation by this plugin. Here's a few examples:

// "firstName" and "lastName" will be observed.
get fullName() {  
  return `${this.firstName} ${this.lastName}`;
}
// "isLoggedIn", "user" and "user.name" will be observed.
get userName() {  
  return this.isLoggedIn ? this.user.name : '(Anonymous)';
}
// "count" will be observed.
get shoppingCartDescription() {  
  return this.count + ' ' + this.pluralize('item', this.count);
}
var _bar = 'baz';

export class Foo {

  // This property cannot be observed by aurelia-computed.
  // Dirty-checking will be required.
  // "_bar" can't be accessed from the binding scope.
  get bar() {
    return _bar;
  }
}

Other options

Aurelia's binding system already has a method for observing computed properties- the @computedFrom decorator. Simply decorate any property with @computedFrom(propertyName1[, propertyName2..., propertyNameN]) and Aurelia's binding system will observe the specified properties and re-evaluate bindings when any of the properties change. The aurelia-computed plugin simply automateds the dependency identification and is able to support more complex scenarios such as observing property paths (this.aurelia.computed.supports.me). There's also the dirty-checking fallback which isn't anything to worry about most of the time.

Development Logging

Enable debug logging in your application (see below for instructions) to view aurelia-computed's log messages. Aurelia-computed logs when it's not able to parse a property getter function or when the function's logic is not observable. This will tell you when Aurelia is going to use dirty-checking. Here's an example:

<template>  
  Thanos wants ${whatThanosWants}
</template>  
var infinityStones = ['Soul','Time','Space','Mind','Reality','Power'];

export class Thanos {  
  get whatThanosWants() {
    return infinityStones;
  }
}

Since infinityStones is declared in the module scope, which binding cannot access, aurelia-computed logs the following message:

console

Get Started

1) Install aurelia-computed:

jspm install aurelia-computed  

2) Use the plugin in your app's main.js:

export function configure(aurelia) {  
  aurelia.use
    .standardConfiguration()
    // enable debug logging to see aurelia-computed's messages.
    .developmentLogging()
    // install the plugin
    .plugin('aurelia-computed');

  aurelia.start().then(a => a.setRoot());
}

Dependencies