AngularJS les meilleures pratiques pour la déclaration de module?

j'ai un tas de modules angulaires déclarés dans mon application. J'ai commencé à les déclarer en utilisant la syntaxe "enchaîné" comme ceci:

angular.module('mymodule', [])
    .controller('myctrl', ['dep1', function(dep1){ ... }])
    .service('myservice', ['dep2', function(dep2){ ... }])
    ... // more here

mais j'ai décidé que ce n'était pas très facile à lire, donc j'ai commencé à les déclarer en utilisant une variable de module comme ceci:

var mod = angular.module('mymodule', []);

mod.controller('myctrl', ['dep1', function(dep1){ ... }]);

mod.service('myservice', ['dep2', function(dep2){ ... }]);
...

la seconde syntaxe me semble beaucoup plus lisible, mais ma seule plainte est que cette syntaxe laisse la variable mod en dehors de la portée globale. Si jamais je avoir une autre variable appelée mod , il serait dépassé avec cette prochaine (et d'autres problèmes associés aux variables globales).

donc ma question Est, est-ce la meilleure façon? Ou serait-il mieux de faire quelque chose comme cela?:

(function(){
    var mod = angular.module('mymod', []);
    mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
    mod.service('myservice', ['dep2', function(dep2){ ... }]);
    ...
})();

ou est-ce assez important pour s'en soucier? Je suis juste curieux de savoir quelles sont les "meilleures pratiques" pour la déclaration des modules. Merci à l'avance.

113
demandé sur tennisgent 2013-11-13 19:10:39

7 réponses

"meilleure façon de déclarer un module

comme l'angle est sur la portée globale elle-même et les modules sont enregistrés à sa variable, vous pouvez accéder aux modules via angular.module('mymod') :

// one file
// NOTE: the immediately invoked function expression 
// is used to exemplify different files and is not required
(function(){
   // declaring the module in one file / anonymous function
   // (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
   // which are very hard to dedect)
   angular.module('mymod', []);
})();


// another file and/or another anonymous function
(function(){   
 // using the function form of use-strict...
 "use strict";
  // accessing the module in another. 
  // this can be done by calling angular.module without the []-brackets
  angular.module('mymod')
    .controller('myctrl', ['dep1', function(dep1){
      //..
    }])

  // appending another service/controller/filter etc to the same module-call inside the same file
    .service('myservice', ['dep2', function(dep2){ 
    //... 
    }]);

  // you can of course use angular.module('mymod') here as well
  angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
      //..
  }])
})();

aucune autre variable globale n'est requise.

bien sûr, tout dépend des préférences, mais je pense que c'est un peu la meilleure pratique, comme

  1. vous n'avez pas à polluer le mondial champ d'application
  2. vous pouvez accéder à vos modules partout et les trier ainsi que leurs fonctions dans différents fichiers à volonté
  3. vous pouvez utiliser la fonction-Forme De "utiliser strict";
  4. l'ordre de chargement des fichiers n'a pas autant d'importance

Options pour trier vos modules et fichiers

cette façon de déclarer et d'accéder aux modules vous rend très flexible. Vous pouvez trier les modules par Fonction-type (comme décrit dans une autre réponse) ou par route, par exemple:

/******** sorting by route **********/    
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...

la façon dont vous le trier à la fin est une question de goût personnel et l'échelle et le type du projet. Personnellement, j'aime regrouper tous les fichiers d'un module à l'intérieur d'un même dossier (ordonné dans des sous-dossiers de directives, contrôleurs, services et filtres), y compris tous les fichiers de test différents, car cela rend vos modules plus réutilisables. Ainsi, dans les projets de taille moyenne, Je avec un module de base, qui inclut toutes les routes de base et leurs contrôleurs, services, directives et sous-modules plus ou moins complexes, quand je pense qu'ils pourraient être utiles pour d'autres projets aussi bien,par exemple:

/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...

angular.module('app', [
  'app.directives',
  'app.filters',
  'app.controllers',
  'app.services',
  'myMapSubModule'
]);

angular.module('myMapSubModule',[
   'myMapSubModule.controllers',
   'myMapSubModule.services',
   // only if they are specific to the module
   'myMapSubModule.directives',
   'myMapSubModule.filters'
]);

pour les très grands projets, je finis parfois par regrouper des modules par routes, comme décrit ci-dessus ou par quelques routes principales sélectionnées ou même une combinaison de routes et de certains composants sélectionnés, mais cela dépend vraiment.

Modifier: Juste parce qu'il est lié et je suis tombé sur cela très récemment encore: prenez bien soin que vous créez un module qu'une seule fois (en ajoutant un deuxième paramètre à l'angle.module de fonction). Cela va gâcher votre demande et peuvent être très difficiles à détecter.

2015 modifier sur les modules de tri: Un an et demi d'expérience angulaire plus tard, je peux ajouter que les avantages d'utiliser des modules nommés différemment dans votre application est quelque peu limitée car AMD ne fonctionne toujours pas vraiment bien avec Angular et les services, les directives et les filtres sont globalement disponibles à l'intérieur du contexte angulaire de toute façon ( comme illustré ici ). Il y a encore un avantage sémantique et structurel et il pourrait être utile de pouvoir inclure / exclure un module avec une seule ligne de code commentée dans ou hors.

il aussi presque n'a jamais beaucoup de sens de séparer les sous-modules par type (eg. "myMapSubModule.controllers') comme ils dépendent généralement l'un de l'autre.

116
répondu hugo der hungrige 2017-05-23 12:34:36

j'aime angulaires-styleguide par Johnpapa, et voici quelques règles qui ont trait à cette question:

Règle: Nommé vs Fonctions Anonymes

éviter d'utiliser des fonctions anonymes:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', function() { })

à la place, utilisez les fonctions nommées:

// dashboard.js
angular
  .module('app')
  .controller('Dashboard', Dashboard);

function Dashboard() { }

comme le dit l'auteur: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.

Règle: Définir 1 composant par fichier.

éviter plusieurs composants dans un fichier:

angular
  .module('app', ['ngRoute'])
  .controller('SomeController', SomeController)
  .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }

au lieu d'utiliser un fichier pour définir le module:

// app.module.js
angular
  .module('app', ['ngRoute']);

un fichier utilise le module pour définir un composant

// someController.js
angular
  .module('app')
  .controller('SomeController', SomeController);

function SomeController() { }

et un autre fichier pour définir un autre composant

// someFactory.js
angular
  .module('app')
  .factory('someFactory', someFactory);

function someFactory() { }

bien sûr, il y a beaucoup d'autres règles pour les modules, les contrôleurs et les services qui sont très utile et digne d'être lu.

et grâce au commentaire de ya_dimon, le code ci-dessus devrait être enveloppé dans IIFE, par exemple:

(function (window, angular) {
  angular.module('app')
   .controller('Dashboard', function () { });
})(window, window.angular);
26
répondu aqingsao 2016-04-01 05:50:02

j'ai récemment eu cette énigme aussi. J'avais commencé comme vous en utilisant la syntaxe enchaînée, mais à long terme, cela devient compliqué avec les grands projets. Normalement, je créerais un module de contrôleurs, un module de services et ainsi de suite dans des fichiers séparés et je les injecterais dans mon module d'application principal trouvé dans un autre fichier. Par Exemple:

// My Controllers File
angular.module('my-controllers',[])
    .controller('oneCtrl',[...])
    .controller('twoCtrl',[...]);

// My Services File
angular.module('my-services',[])
    .factory('oneSrc',[...])
    .facotry('twoSrc',[...]);

// My Directives File
angular.module('my-directives',[])
    .directive('oneDrct',[...])
    .directive('twoDrct',[...]);

// My Main Application File
angular.module('my-app',['my-controllers','my-services','my-directives',...]);

mais chacun de ces dossiers prenait de l'ampleur au fur et à mesure que le projet prenait de l'ampleur. J'ai donc décidé de les diviser en des fichiers séparés basés sur chaque contrôleur ou service. J'ai découvert que l'utilisation de angular.module('mod-name'). sans la matrice d'injection, est ce dont vous avez besoin pour que cela fonctionne. Déclarer une variable globale dans un fichier et s'attendre à ce qu'elle soit facilement disponible dans un autre fichier ne fonctionne tout simplement pas ou pourrait avoir des résultats inattendus.

bref, ma demande ressemblait à quelque chose comme ceci:

// Main Controller File
angular.module('my-controllers',[]);

// Controller One File
angular.module('my-controllers').controller('oneCtrl',[...]);

//Controller Two File
angular.module('my-controllers').controller('twoCtrl',[...]);

j'ai fait ceci au fichier de services aussi bien, pas besoin de changer le principal vous y injecteriez encore les mêmes modules.

12
répondu m.e.conroy 2013-11-13 15:47:05

une autre pratique est de bourrer les contrôleurs, les directives, etc dans leurs propres modules et d'injecter ces modules dans votre "principal":

angular.module('app.controllers', [])
  .controller('controller1', ['$scope', function (scope) {
    scope.name = "USER!";
  }]);

angular.module('app.directives', [])
  .directive('myDirective', [function () {
    return {
      restrict: 'A',
      template: '<div>my directive!</div>'
    }
  }]);

angular.module('app', [
  'app.controllers',
  'app.directives'
]);

Rien n'est laissé dans la portée globale.

http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview

8
répondu Manny D 2013-11-13 15:43:15

j'aime diviser mes fichiers et mes modules.

quelque chose comme ça:

app.js

var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']);

myApp.config(['$routeProvider', function($routeProvider) {
    /* routes configs */
    $routeProvider.when(/*...*/);
}]);
"151930920 des" directives".js

var myDirectives = angular.module('myApp.directives', []);

myDirectives.directive( /* ... */ );

de service.js

var myServices = angular.module('myApp.services', []);

myServices.factory( /* ... */ );

Je ne suis pas un grand fan du" style enchaîné", donc je préfère écrire toujours ma variable.

4
répondu Beterraba 2013-11-13 15:42:40

pour moi, l'enchaînement est la manière la plus compacte:

angular.module("mod1",["mod1.submod1"])

 .value("myValues", {
   ...
 })

 .factory("myFactory", function(myValues){
   ...
 })

 .controller("MainCtrl", function($scope){

   // when using "Ctrl as" syntax
   var MC = this;
   MC.data = ...;
 })
 ;

de cette façon je peux facilement déplacer des composants entre les modules, jamais besoin de déclarer le même module deux fois, jamais besoin de variables globales.

et si le fichier devient trop long, la solution est simple - divisé en deux fichiers, chacun déclarant son propre module au sommet. Pour plus de transparence, j'essaie de garder un module unique par fichier et de le nommer ressemblant au chemin complet du fichier. De cette façon aussi je n'ai jamais besoin d'écrire un module sans [] , qui est une douleur commune point.

0
répondu Dmitri Zaitsev 2014-08-11 16:51:12

je vous suggère de suivre Guide de style Angularjs .

Ils gèrent tout le concept de la convention de nommage, pour modulariser votre application et ainsi de suite.

pour angular 2, Vous pouvez cocher Guide de Style Angular 2

0
répondu user3444693 2017-09-06 03:03:57