Implémentation du Chargement Dynamique de Services avec AngularAMD

L'optimisation des applications monopages (SPA) repose souvent sur le chargement asynchrone des composants. Après avoir maîtrisé le chargement différé des contrôleurs, l'étape suivante consiste à appliquer la même logique aux services. L'utilsiation d'AngularAMD permet d'alléger le démarrage initial de l'application en ne chargeant les services qu'au moment où ils sont strictement nécessaires. Cette approche modulaire améliore non seulement les performances perçues par l'utilisateur, mais facilite également la maintenance du code.

Création d'un Service Modulaire

Pour illustrer ce concept, nous allons créer un service dédié à la gestion d'un catalogue de produits. Ce service sera encapsulé dans un module AMD pour être chargé à la demande. Créez un fichier nommé ProductCatalog.js.

La première étape consiste à envelopper le code dans une définition RequireJS, en injectant l'objet app fourni par AngularAMD pour permettre l'enregistrement dynamique du service. Nous définissons ensuite la logique métier en utilisant une approche orientée objet. La classe ProductCatalog initialisera une collection de produits et exposera une méthode pour rechercher un article spécifique par son identifiant (SKU). Une fois la classe définie, elle est enregistrée dynamiquement dans le module Angular.

define(["app"], function (app) {
    
    var ProductCatalog = (function () {
        
        function ProductCatalog() {
            this.inventory = [
                { sku: "A100", name: "Clavier Mécanique", category: "Périphériques" },
                { sku: "B200", name: "Écran 4K", category: "Moniteurs" },
                { sku: "C300", name: "Souris Ergonomique", category: "Périphériques" }
            ];
        }

        ProductCatalog.prototype.getArticleBySku = function (targetSku) {
            var foundItem = null;
            for (var i = 0; i < this.inventory.length; i++) {
                if (this.inventory[i].sku === targetSku) {
                    foundItem = this.inventory[i];
                    break;
                }
            }
            return foundItem;
        };

        return ProductCatalog;
    })();

    app.service("ProductCatalog", [ProductCatalog]);
});

Intégration et Chargement dans un Contrôleur

Maintenant que le service est prêt, il doit être consommé par un contrôleur. Supposons que nous ayons un contrôleur pour une page de catalogue, défini dans catalog.js. Nous devons modifier les dépendances de ce fichier pour inclure notre nouveau module.

En ajoutant "ProductCatalog" dans le tableau des dépendances de RequireJS, le chargeur de modules ira chercher et exécuter ProductCatalog.js avant d'initialiser le contrôleur. Le service étant désormais enregistré dans l'injecteur Angular, il peut être injecté directement dans la fonction du contrôleur pour récupérer un produit spécifique et l'attacher au $scope.

define(["ProductCatalog"], function () {
    
    return ["$scope", "ProductCatalog", function ($scope, ProductCatalog) {
        $scope.pageTitle = "Détails du Produit";
        $scope.currentItem = ProductCatalog.getArticleBySku("B200");
    }];
    
});

Mise à Jour de la Vue

Le template HTML associé (catalog.html) peut maintenant afficher les données récupérées de manière asynchrone. Les expressions AngularJS se chargeront de lier les propriétés du scope à l'interface utilisateur.

<h2>{{ pageTitle }}</h2>
<div class="product-details">
    <p>Nom : {{ currentItem.name }}</p>
    <p>Catégorie : {{ currentItem.category }}</p>
    <p>SKU : {{ currentItem.sku }}</p>
</div>
<button ui-sref="home">Retour à l'accueil</button>

Vérification du Chargement Asynchrone

Pour valider le comportement de chargement différé, lancez l'application et ouvrez les outils de développement de votre navigateur (onglet Réseau). Lors du chargement initial de la page d'accueil, le fichier ProductCatalog.js ne doit pas apparaître dans les requêtes réseau.

Ce n'est qu'au moment de la navigation vers la route associée au contrôleur catalog.js que le navigateur effectuera une requête XHR pour télécharger le service. Cette confirmation visuelle garantit que l'architceture modulaire fonctionne correctement et que le poids initial de l'application est optimisé. Si vous testez en local via le protocole file://, assurez-vous de configurer votre navigateur pour autoriser les requêtes cross-origin locales ou utilisez un serveur web local simple pour éviter les blocages de sécurité liés aux requêtes AJAX.

Étiquettes: angularjs AngularAMD RequireJS AMD SPA

Publié le 19 juin à 16h39