1

J'ai hérité du code qui utilise un objet global pour stocker les services angulaires. Ces services sont attachés à l'objet global dans la fonction d'exécution du module angulaire. Ma question est la suivante: cela peut-il causer des problèmes sur la route? Quel genre de problème cela cause-t-il pour les tests? Passer de tels services semble beaucoup plus facile que d'injecter tous les services dans chaque contrôleur, donc je vois pourquoi cela est fait. Quels sont les autres arguments pour ne pas le faire? Voici un code pour illustrer de quoi je parle:Éviter l'injection de dépendance angulaire à l'aide de l'objet global

// vars 
var globalObject = 
{ 
    ng: {}, 
}; 

// Setup module 
var myModule = angular.module("myModule", []); 
myModule.config(doStuff); 
myModule.run(setUpGlobals); 

// Setup app globals 
function setUpGlobals(ngRootScope, ngHttp, ngTimeout) 
{ 
    globalObject.rootScope = ngRootScope; 

    // angular services 
    globalObject.ng.http = ngHttp; 
    globalObject.ng.Timeout = ngTimeout; 
} 
setUpGlobals.$inject = ['$rootScope', '$http', '$timeout']; 

Répondre

1

Les modules et DI ont été introduits dans Angular exactement pour éviter de compter sur les globaux et améliorer la modularité.

Cette approche naïve ne fonctionne que s'il existe un seul module et une seule instance d'application. Il échouera s'il y a plusieurs modules qui peuvent être utilisés séparément (y compris les tests). Cela produira des bugs horribles s'il y a plus d'une instance d'application sur la page (par exemple, si Angular est utilisé pour des applications non-SPA).

Un module monolithe nuit à la testabilité. Même s'il est utilisé comme cela, certaines options ne seront pas disponibles, par ex. injecter des services espion ou stubbed dans $controller(...) - parce qu'un contrôleur repose sur des globals.

setUpGlobals entraîne une instanciation du service. Cela ne pose peut-être pas de problème pour les services de base, mais sera un problème pour les services qui n'ont pas besoin d'être instanciés en ce moment.

La taille du code dans l'application minifiée est une préoccupation moins importante. ng.$rootScope peut être réduit à a.$rootScope mais pas plus loin. La fonction annotée doit mentionner une seule fois la chaîne '$rootScope', mais le nom de la variable $rootScope peut être réduit à a. Il y aura des améliorations si un service est utilisé plus d'une fois dans une fonction.

Il y a beaucoup de raisons why global variables are bad. Certains d'entre eux ne seront pas applicables dans ce cas, d'autres le seront.

+0

Merci! Je n'étais pas au courant que les services sont instanciés à la demande. https://www.bennadel.com/blog/2715-services-and-factories-are-instantiated-on-demand-in-angularjs.htm –

+1

De rien. La plupart du temps, cela ne pose pas de problème, mais cela peut casser des fonctionnalités qui reposent sur un comportement naturel, par exemple un chargement paresseux. – estus

+0

encore une question: les services agissent-ils comme des singletons entre différents modules? Ils font pour le même module mais si le module A et le module B injectent serivce 1, le service 1 sera-t-il partagé? –

1

Cela rend le test nightmaraish. Dependency Injection est génial, car cela signifie que vous pouvez faire quelques tests atomiques, en se moquant des services dont vous n'avez pas besoin. Dans un exemple simple, non convolé, imaginez un service qui effectue des appels d'API via http, si vous l'introduisez, votre test peut simuler le http et simuler un retour, vous permettant de tester seulement les bits de code que vous voulez, et vous éviter d'avoir un test qui repose sur l'API, ou pire un test qui utilise vos appels d'API. Avec le fournisseur dans la portée mondiale, c'est beaucoup plus difficile à réaliser. Juste une raison, je suis sûr qu'il y en a beaucoup d'autres.

+0

En fait, les tests ne seront pas si mauvais - tant qu'il n'y a qu'un seul module, les globales seront réattribuées à chaque test. Mais le point que cela ne doit pas être unique. Et il y aura des problèmes une fois que ce n'est pas le cas. – estus