web-dev-qa-db-fra.com

AngularJS seed: placer JavaScript dans des fichiers séparés (app.js, controllers.js, directives.js, filters.js, services.js)

J'utilise le modèle angular-seed pour structurer mon application. Au départ, je mets tout mon code JavaScript dans un seul fichier, main.js. Ce fichier contenait ma déclaration de module, des contrôleurs, des directives, des filtres et des services. L’application fonctionne bien de cette façon, mais je crains l’évolutivité et la facilité de maintenance à mesure que mon application devient plus complexe. J'ai remarqué que le modèle de graine angulaire avait des fichiers séparés pour chacun d'eux. J'ai donc essayé de distribuer mon code à partir du single main.js fichier dans chacun des autres fichiers mentionnés dans le titre de cette question et trouvés dans le fichier app/js répertoire du modèle angular-seed .

Ma question est la suivante: comment gérer les dépendances pour que l'application fonctionne? La documentation existante trouvée ici n'est pas très claire à cet égard puisque chacun des exemples donnés montre un fichier source JavaScript unique.

Un exemple de ce que j'ai est:

app.js

angular.module('myApp', 
    ['myApp.filters',
     'myApp.services',
     'myApp.controllers']);

controllers.js

angular.module('myApp.controllers', []).
    controller('AppCtrl', [function ($scope, $http, $filter, MyService) {

        $scope.myService = MyService; // found in services.js

        // other functions...
    }
]);

filtres.js

angular.module('myApp.filters', []).
    filter('myFilter', [function (MyService) {
        return function(value) {
            if (MyService.data) { // test to ensure service is loaded
                for (var i = 0; i < MyService.data.length; i++) {
                    // code to return appropriate value from MyService
                }
            }
        }
    }]
);

services.js

angular.module('myApp.services', []).
    factory('MyService', function($http) {
        var MyService = {};
        $http.get('resources/data.json').success(function(response) {
            MyService.data = response;
        });
        return MyService;
    }
);

main.js

/* This is the single file I want to separate into the others */
var myApp = angular.module('myApp'), []);

myApp.factory('MyService', function($http) {
    // same code as in services.js
}

myApp.filter('myFilter', function(MyService) {
    // same code as in filters.js
}

function AppCtrl ($scope, $http, $filter, MyService) {
    // same code as in app.js
}

Comment gérer les dépendances?

Merci d'avance.

93
ChrisDevo

Le problème provient de la "nouvelle déclaration" de votre module d'application dans tous vos fichiers séparés.

Voici à quoi ressemble la déclaration du module d'application (la déclaration incertaine est le suivant):

angular.module('myApp', []).controller( //...

Voici à quoi ressemble l'affectation (à savoir si l'affectation est le bon terme) pour votre module d'application:

angular.module('myApp').controller( //...

Notez le manque de crochets.

Ainsi, la version précédente, un avec les crochets, ne devrait être utilisée qu'une seule fois, généralement dans votre app.js ou main.js. Tous les autres fichiers associés - contrôleurs, directives, filtres… - doivent utiliser la dernière version, celle sans les crochets.

J'espère que cela à du sens. À votre santé!

108
Justin L.

Si vous souhaitez placer vos différentes parties de votre application (filters, services, controllers) Dans des fichiers physiques différents, vous devez procéder de deux manières:

  1. Déclarez ces espaces de noms (faute d'un meilleur terme) dans votre app.js Ou dans chaque fichier;
  2. Reportez-vous à ces espaces de noms dans chacun des fichiers.

Ainsi, votre app.js Ressemblerait à ceci:

angular.module('myApp', ['external-dependency-1', 'myApp.services', 'myApp.controllers'])
.run(function() {
   //...

})
.config(function() {
  //...
});

Et dans chaque fichier individuel:

services.js

angular.module('myApp.services', []); //instantiates
angular.module('myApp.services') //gets
.factory('MyService', function() { 
  return {};
});

controllers.js

angular.module('myApp.controllers', []); //instantiates
angular.module('myApp.controllers')      //gets
.controller('MyCtrl', function($scope) {
  //snip...
})
.controller('AccountCtrl', function($scope) {
  //snip...
});

Tout cela peut être combiné en un seul appel:

angular.module('myApp.controllers', []) 
.controller('MyCtrl', function($scope) {
 //snip...
});    

La partie importante est que vous ne devriez pas redéfinir angular.module('myApp'); cela provoquerait son écrasement lorsque vous instancierez vos contrôleurs, probablement pas ce que vous voulez.

11
George Stocker

Vous obtenez l'erreur car vous n'avez pas défini myApp.services encore. Ce que j'ai fait jusqu'à présent, c'est de mettre toutes les définitions initiales dans un fichier, puis de les utiliser dans un autre. Comme pour votre exemple je mettrais dans:

app.js

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

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

Cela devrait éliminer l'erreur, mais je pense que vous devriez lire l'article Eduard Gamonal mentionné dans l'un des commentaires.

3