Семя AngularJS: включение JavaScript в отдельные файлы (app.js, controllers.js, directives.js, filters.js, services.js)

Я использую шаблон angular-seed для структурирования моего приложения. Первоначально я поместил весь свой код JavaScript в один файл, main.js. Этот файл содержал мое объявление модуля, контроллеры, директивы, фильтры и службы. Приложение работает так, как это, но я беспокоюсь о масштабируемости и ремонтопригодности, поскольку мое приложение становится более сложным. Я заметил, что шаблон angular -seed имеет отдельные файлы для каждого из них, поэтому я попытался распространять свой код из одного файла main.js в каждый из других файлов, упомянутых в заголовке, на этот вопрос и найден в каталог app/js шаблона angular-seed.

Мой вопрос: как мне управлять зависимостями, чтобы заставить приложение работать? Существующая документация, найденная здесь, не очень понятна в этом отношении, поскольку каждый из приведенных примеров показывает один исходный файл JavaScript.

Пример того, что у меня есть:

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...
    }
]);

filters.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
}

Как управлять зависимостями?

Спасибо заранее.

Ответ 1

Проблема вызвана тем, что вы обновляете свой модуль приложения во всех своих отдельных файлах.

Это то, что объявление модуля приложения (не уверенное объявление - правильный термин) выглядит следующим образом:

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

Это то, что присваивание (не уверен, что назначение является правильным термином), к вашему прикладному модулю выглядит следующим образом:

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

Обратите внимание на отсутствие квадратных скобок.

Итак, предыдущая версия, одна с квадратными скобками, должна использоваться только один раз, обычно в app.js или main.js. Все остальные связанные файлы - контроллеры, директивы, фильтры... - должны использовать последнюю версию, без квадратных скобок.

Надеюсь, это имеет смысл. Ура!

Ответ 2

Если вы хотите разместить свои разные части приложения (filters, services, controllers) в разных физических файлах, вам нужно сделать две вещи:

  • Объявить эти пространства имен (из-за отсутствия лучшего термина) в вашем app.js или в каждом файле;
  • Обратитесь к этим пространствам имен в каждом из файлов.

Итак, ваш app.js будет выглядеть так:

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

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

И в каждом отдельном файле:

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...
});

Все это можно объединить в один вызов:

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

Важная часть заключается в том, что вы не должны переопределять angular.module('myApp'); что приведет к его перезаписыванию при создании экземпляров ваших контроллеров, возможно, не в том, что вы хотите.

Ответ 3

Вы получаете сообщение об ошибке, поскольку пока не определили myApp.services. То, что я сделал до сих пор, заключается в том, чтобы поместить все начальные определения в один файл, а затем использовать их в другом. Как и для вашего примера, я бы добавил:

app.js

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

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

Это должно избавиться от ошибки, хотя я думаю, что вы должны прочитать в статье Эдуард Гамонал, упомянутый в одном из комментариев.