Créer un Component AngularJS en TypeScript

Fin 2015, j'ai écrit un article expliquant comment écrire du code AngularJS en utilisant TypeScript. On avait vu comment déclarer un contrôleur, un filtre, une directive, etc. En reprenant un ancien projet AngularJS, je me suis rendu compte que je n'avais pas expliqué la syntaxe permettant de créer un composant (pour ma défense, cette notion n'existait pas encore et a été apportée par AngularJS 1.5).

Pour résumer très rapidement, un composant AngularJS reprend la logique et le principe des composants Angular (la nouvelle version) : créer des éléments simples et réutilisables, composer son application en assemblant un ensemble de composants, etc. L'un des avantages à les utiliser est qu'ils permettent une migration un peu plus douce vers Angular.

Déclaration du composant en TypeScript

Pour déclarer un composant, il faut commencer par créer une classe représentant son contrôleur (dans l'exemple suivant un simple contrôleur permettant d'incrément ou décrémenter une propriété). A noter que la propriété statique $inject permet d'indiquer à AngularJS quels sont les éléments à injecter dans le contrôleur.

class MoreLessComponentController
{
    static $inject: string[] = [];
    value: number;

    constructor() {
        this.value = this.value || 0;
    }

    more = () => {
        this.value++;
    };

    less = () => {
        if (this.value > 0) {
            this.value--;
        }
    };
}

Ensuite il faut déclarer le composant en lui-même en créant une classe implémentant ng.IComponentOptions :

class MoreLessComponent implements ng.IComponentOptions
{
    controllerAs = 'vm';
    controller = MoreLessComponentController;
    bindings = {
        value: '='
    };

    template: string = `
        <div class='more-less'>
            <button data-ng-click='vm.more()'>+</button>
            <button data-ng-disabled='vm.value <= 0' data-ng-click='vm.less()'>-</button>
        </div>
    `;
}

angular.module('easypass').component('moreLess', new MoreLessComponent());

La propriété bindings permet de faire le mapping entre les propriétés du contrôleur et celles exposées par le composant. A noter également que la relation entre le composant et son contrôleur se fait en renseignant le type du contrôleur via la propriété controller. L'enregistrement du composant dans le module AngularJS se fait en lui passant une instance de composant.

Utilisation de décorateurs

Si vous avez fait un peu d'Angular (nouvelle version), vous avez sans doute pu goûter aux décorateurs. Et pourquoi est-ce qu'on ne reproduirait pas une syntaxe similaire avec AngularJS ?

Pour cela, il faut commencer par créer le décorateur en lui-même, qui sera chargé d'enregistrer le composant.

function Component(moduleOrName: string | ng.IModule, selector: string, options: ng.IComponentOptions) {
    return (controller: Function) => {
        var module = typeof moduleOrName === "string" ? angular.module(moduleOrName) : moduleOrName;
        module.component(selector, angular.extend(options, { controller: controller }));
    }
}

La déclaration du composant se fait alors directement dans le décorateur, au dessus de la classe servant de contrôleur :

@Component('easypass', 'moreLess', {
    controllerAs: 'vm',
    bindings: {
        value: '='
    },
    template: `
        <div class='more-less'>
            <button data-ng-click='vm.more()'>+</button>
            <button data-ng-disabled='vm.value <= 0' data-ng-click='vm.less()'>-</button>
        </div>`
})
class MoreLessComponent {
    value: number;

    constructor() {
        this.value = this.value || 0;
    }

    more = () => {
        this.value++;
    };

    less = () => {
        if (this.value > 0) {
            this.value--;
        }
    };
}

Plutôt cool non ? On n'est plus obligé de créer une classe représentant le composant (on déclare ici uniquement le contrôleur) et toute la déclaration technique se fait via le décorateur. Attention, pour utiliser cette syntaxe il faut ajouter le paramètre experimentalDecorators à true lors de la compilation TypeScript.

Et voilà, vous pouvez créer vos composants AngularJS assez facilement en TypeScript.

Bons composants !

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus