1. Injection de dépendance
L'injection de dépendance (DI) est un modèle de conception logicielle qui traite de la façon dont le code obtient les ressources dont il dépend.
Pour une discussion plus approfondie sur DI, vous pouvez visiter l'injection de dépendance (http://en.wikipedia.org/wiki/dependency_injection), Inversion of Control (http://martinfowler.com/articles/injection.html), ou vous pouvez visiter le livre sur des motifs de conception logicielle.
1. DI en un mot (simplement parlant di)
L'objet ou la fonction ne peut obtenir que les ressources sur lesquelles ils dépendent des trois façons suivantes:
1) Vous pouvez créer des ressources dépendantes via le nouvel opérateur.
2) Vous pouvez trouver des ressources dépendantes par le biais de variables mondiales.
3) Les ressources dépendantes peuvent être transmises à travers des paramètres.
Les deux méthodes 1 et 2 ne sont pas les meilleures, car elles codent dur les dépendances, ce qui ne rend pas impossible de modifier les dépendances, mais elle deviendra plus compliquée. C'est particulièrement un problème pour les tests, et généralement lors des tests indépendamment, il est souhaité fournir des dépendances simulées.
La troisième méthode est relativement la plus réalisable car elle supprime la responsabilité de localiser les dépendances des composants. La dépendance est juste remise aux composants.
fonction SomeClass (Greeter) {this.greeter = greeter} Someclass.prototype.dosomething = function (name) {this.greeter.greet (name);}Dans l'exemple ci-dessus, SomeClass n'a pas besoin de se soucier de localiser la dépendance Greeter, il ne passe que Greeter au moment de l'exécution.
Ceci est plus approprié, mais il laisse la responsabilité d'obtenir les ressources de dépendance au code responsable de la construction de Someclass.
Pour gérer la responsabilité de la création de dépendances, chaque application angulaire a un injecteur (http://code.angularjs.org/1.0.2/docs/api/angular.injector). L'injecteur est un localisateur de services responsable de la localisation et de la création de ressources dépendantes.
Demandez les dépendances, résout le problème du code dur, mais cela signifie que l'injecteur doit exécuter l'ensemble de l'application. Le passage de l'injecteur détruira la loi de Demeter (http://baike.baidu.com/view/823220.htm). Pour corriger ce problème, nous transférons la responsabilité des recherches de dépendance à l'injecteur.
J'ai dit tellement de choses ci-dessus. Regardez les exemples que j'ai modifiés ci-dessous. J'ai fusionné deux exemples du texte d'origine, en utilisant Inject à l'intérieur et à l'extérieur Angular:
<! Doctype html> <html lang = "zh-cn" ng-app = "MainApp"> <éadf> <meta charset = "utf-8"> <itle> injector </ title> </ head> <body> <div ng-controller = "myController"> <bouton ng-Click = "Sayhello ()"> Say Hello src = "../ angular-1.0.1.js" type = "text / javascript"> </ script> <script type = "text / javascript"> // Créer le module autremodule, qui est équivalent au module externe var autre autreModule = angular.module ("autremodule", []); // Enseigner l'injecteur comment créer "greeter" // notez que Greeter lui-même doit s'appuyer sur $ window othermodule.factory ("greeter", function ($ window) {// il s'agit d'une méthode d'usine, responsable de la création du service de salut {relevance: function (text) {$ window.alert (text);}};}); // Ce qui suit montre que dans un module non courant, appelez la méthode de salut via l'injecteur: // Créez un nouvel injecteur à partir du module // Cette étape est généralement effectuée automatiquement lorsque l'angulaire est démarré. // Les choses angulaires «ng» doivent être introduites // L'ordre est délibérément inversé, et il est temporairement confirmé que l'ordre de cette chose n'a pas d'importance. . var injecteur = angular.injector (['autremodule', 'ng']); // demande la dépendance de Greeter. var g = injecteur.get ("greeter"); // l'appelle directement ~ g.greet ("Hi ~ mon petit dada ~"); // Il s'agit de l'application principale actuelle, et vous devez compter sur autremodule var mainApp = angular.module ("mainApp", ["autremodule"]); // Faites attention aux paramètres de la fonction de définition du contrôleur, et injectez directement $ Scope et Greeter ici. // Le service Greeter est mainApp.Controller ("MyController", fonction MyController ($ scope, greeter) {$ scope.sayhello = function () {greeter.greet ("Hello Kitty ~~");};}); // Ng-Controller a fait cette chose silencieusement dans les coulisses //injector.instantiate(myController); </cript> </body> </html>Notez que comme il y a un contrôleur NG, MyController est initialisé, il peut répondre à toutes les dépendances de MyController, afin que MyController n'ait pas besoin de connaître l'existence de l'injecteur. C'est le meilleur résultat. Le code d'application demande simplement les dépendances dont il a besoin sans gérer l'injecteur. Ce cadre ne va pas enfreindre la loi de Demeter.
2. Annotation de dépendance (commentaires de dépendance, expliquant la voie des dépendances)
Comment l'injecteur sait-il quel service doit être injecté?
Les développeurs d'applications doivent fournir des informations d'annotation utilisées par l'injecteur comme solution aux dépendances. Toutes les fonctions d'API existantes dans Angular font référence à l'injecteur, et c'est le cas avec l'API mentionné dans chaque document. Voici trois façons équivalentes d'annoter notre code avec des informations sur le nom du service.
1. Déduire les dépendances
C'est le moyen le plus simple d'obtenir une ressource dépendante, mais il est nécessaire de supposer que le nom du paramètre de la fonction est cohérent avec le nom de la ressource dépendante.
fonction myController ($ scope, greeter) {...}L'injecteur d'une fonction peut deviner le nom du service qui doit être injecté (functionname.toString (), regexp) en vérifiant la définition de la fonction et en extraction du nom de la fonction. Dans l'exemple ci-dessus, $ Scope et Greeter sont deux services qui doivent être injectés dans la fonction (les noms sont également les mêmes).
Bien que cela soit simple, cette méthode ne fonctionnera pas après la compression de l'obscurcation JavaScript, car le nom du paramètre sera modifié. Cela rend cette méthode uniquement utile pour le prétotypage (méthode de test de simulation du prototype d'utilisation du produit, http://www.pretotyping.org/, http://tech.qq.com/a/20120217/000320.htm) et applications de démonstration.
2. $ Inject Annotation ($ inject commentaire)
Afin de permettre au compresseur de script de renommer la méthode de la fonction et de pouvoir injecter le service correct, la fonction doit commenter la dépendance via la propriété $ injecte. La propriété $ inject est un tableau des noms des services qui doivent être injectés.
var MyController = fonction (renommé $ scope, renomméGreeter) {...} // Si la chose qui dépend ici n'est pas dans le module actuel, il ne le reconnaît toujours pas. // Vous devez d'abord compter sur le module correspondant dans le module actuel. C'est similaire à l'exemple précédent. Mais je ne sais pas si c'est la bonne façon.
MyController. $ Inject = ['$ scope', 'greeter'];
Il doit être prudent que l'ordre de $ inject doit être conforme à l'ordre des arguments déclarés par la fonction.
Cette méthode d'annotation est utile pour les déclarations du contrôleur car elle spécifie les informations d'annotation avec la fonction.
3. Annotation en ligne (commentaires en ligne)
Parfois, il n'est pas pratique d'utiliser la méthode d'annotation $ inject, comme lors des commentaires directement.
Par exemple:
SomeModule.Factory ('Greeter', fonction ($ Window) {...;});Étant donné que des variables temporaires sont nécessaires (empêchez-les de ne pas être utilisées après la compression), le code se bloquera comme suit:
var greeterFactory = fonction (renommé $ fenêtre) {...;}; greeterFactory. $ inject = ['$ window']; SomeModule.factory ('greeter', greeterFactory);Pour cette raison (Bloat de code), Angular fournit également un troisième style de commentaire:
SomeModule.factory ('Greeter', ['$ window', fonction (renommé $ fenêtre) {...;}]);N'oubliez pas que tous les styles de commentaires sont équivalents et peuvent être utilisés n'importe où dans un angulaire qui soutient l'injection.
3. Où puis-je utiliser DI?
DI est partout dans l'angulaire. Il est généralement utilisé dans les méthodes de contrôleur et d'usine.
1. DI dans les contrôleurs
Le contrôleur est la classe responsable du comportement d'application (décrivant). La méthode de déclaration de contrôleur recommandée est:
var myController = function (dep1, dep2) {...} myController. $ inject = ['dep1', 'dep2']; myController.prototype.amethod = function () {...}2. Méthodes d'usine
La méthode d'usine est responsable de la création de la plupart des objets angulaires. Par exemple, directive, service, filtre. La méthode d'usine est enregistrée dans le module. La méthode de déclaration d'usine recommandée est:
angualar.module ('mymodule', []). config (['Depprovider', fonction (Depprovider) {...}]). Factory ('ServiceId', ['DepService', fonction (DepService) {...}]). Directive ('DiredivenName', ['DepService', fonction (DepService) {...}]). filter ('filterName', ['DepService', fonction (depService) {...}]);Ce qui précède est le résumé des informations sur l'injection de dépendance AngularJS. Merci pour votre soutien à ce site!