Observer le router

Je me remet à Aurelia qui a pas mal évolué depuis ma première tentative. On a maintenant droit à un générateur yeoman, ce qui facilite grandement le démarrage d'un nouveau projet. Pour un nouveau projet, j'ai eu besoin de fonctionnalités qui vont nous permettre de découvrir l'observation d'objets, le binding de propriétés et l'injection de dépendance.

J'ai donc un controller d'une vue instanciée par le routeur de l'application. Pour des besoins particulier, je dois passer un attribut dans l'url en query string. Voici le format de l'url : "/something?type=foobar". Ce que je veux aussi, c'est quand type change, le composant something ne soit pas rechargé. Ça tombe bien, le routeur ignore les query string et ne recharge donc rien. Par contre, il me faut pouvoir écouter les changements de ce query string pour mettre à jour la valeur de type dans mon contrôleur.

Nous allons pour cela injecter Router afin d'avoir accès au routeur parent, et ObserverLocator pour observer les changements de valeur du routeur. Et pour le fun, nous allons aussi utiliser bindable pour voir comment rendre une propriété de classe observable.

import {ObserverLocator} from 'aurelia-framework';  
import {inject} from 'aurelia-framework';  
import {Router} from 'aurelia-router';  
import {bindable} from 'aurelia-framework';

@inject(Router, ObserverLocator)
export class Something{

  @bindable type = 'default';

  constructor (router, ObserverLocator) {
    this._routerObserver = ObserverLocator
      .getObserver(router, 'currentInstruction')
      .subscribe(newVal => {
        let type = newVal.queryString.match(/type=(\w+)/);
        type = type && type[1];
        this.type = type;
      });
  }

  typeChanged () {
    console.log(`this.type has changed : ${this.type}`);
  }

  deactivate () {
    this._routerObserver();
  }
}

Tout d'abord, le décorateur @inject permet de déclarer les dépendances à injecter dans le constructeur de la classe. On injecte donc Router et ObserverLocator.

Ensuite, on déclare la propriété type comme étant observable grâce au décorateur @bindable. Grâce à elle, nous pouvons alors définir une méthode typeChanged(newVal, oldVal) qui sera automatiquement exécutée à chaque fois que la valeur de this.type changera.

Pour finir, nous allons observer le routeur dans le constructeur de la classe. Nous allons donc utiliser ObserverLocator qui est un polyfill de Object.observe pour écouter les changement de valeur de la propriété currentInstruction de Router. Ainsi, à chaque fois que la route changera, nous en serons informés, et nous pourrons lire le queryString et stocker la valeur manuellement. Nous n'oublierons pas d'arrêter l'écoute de l'objet lors de la désactivation du composant grâce à la méthode deactivate pour éviter de gonfler la mémoire pour rien.

Plus de détails à propos de l'observation de propriété ici.

Hadrien

Hi, I'm a french Javascript Lead Developer, Web Architect from Toulouse, France. I've worked for 12 years for many projects with YUI, AngularJS, Aurelia.io and now React and React native.

Toulouse, France https://hadrien.eu