Как я могу иметь несколько файлов контроллера?

РЕШЕНО

Итак, просмотрев ваши ответы и внеся небольшие изменения в свой код, я обнаружил простую опечатку, которая помешала мне достичь результата, к которому я стремился. Так что спасибо всем за помощь в том, где я ошибся, теперь я разделил контроллеры, и все работает, как и планировалось!

----

В настоящее время я разрабатываю гибридное мобильное приложение с использованием Cordova, Ionic и AngularJS в Visual Studio 2015. Из-за огромного количества кода, который у меня есть в моем единственном файле controller.js, я хочу разделить код, чтобы у меня был файл контроллера .js. по шаблону; а не все в одном файле. К сожалению, я не понимаю, как это осуществить (все еще изучаю AngularJS). Я провел некоторые исследования, но большинство примеров, которые я видел, показывают очень простую демонстрацию, которую я воспроизвел со своим собственным кодом, но она все еще не работает. Поэтому я надеялся, что кто-то может дать мне представление о том, где я могу ошибаться.

Структура файла в /www

  • index.html

/js

  • app.js

  • контроллеры.js

/js/контроллеры

  • логин.js

  • продажи.js

/шаблоны

  • логин.html

  • продажи.html

/js/приложение .js

angular.module('main', ['ionic', 'main.controllers', 'chart.js', 'ngCordova', 'ngIOS9UIWebViewPatch', 'angular.filter'])

    .config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
        $stateProvider

        .state('login', {
            cache: false,
            url: "/login",
            templateUrl: "templates/login.html",
            controller: "LoginCtrl"
        })

        .state('sales', {
            cache: false,
            url: "/sales",
            templateUrl: "templates/sales.html",
            controller: "SalesCtrl"
        })

        $urlRouterProvider.otherwise('/login')
        $ionicConfigProvider.views.swipeBackEnabled(false);
    });

/js/controllers.js

angular.module('main.controllers', ['ionic', 'ngCordova']);

/js/controllers/login.js

angular.module('main.controllers', [])
.controller("LoginCtrl", function ($scope, $state, $cordovaSQLite, $timeout, $ionicPopup, $cordovaDevice, $ionicLoading, $cordovaKeyboard, $cordovaToast) {
    $ionicLoading.show({
        template: 'Loading...'
    });
// DO STUFF

/js/controllers/sales/js

angular.module('main.controllers', [])

.controller("SalesCtrl", function ($scope, $state, $http, $ionicLoading, $cordovaSQLite, $cordovaToast) {
    $ionicLoading.show({
        template: 'Loading data...'
    });
// DO STUFF

Следуя этой структуре, я получаю эту ошибку (цитата ниже): https://docs.angularjs.org/error/ng/areq?p0=LoginCtrl&p1=not%20a%20function,%20got%20undefined

Аргумент 'LoginCtrl' не является функцией, стал неопределенным

Мне удалось немного заставить его работать, только когда у меня был login.js, а не sales.js, но, конечно, $state.* перестал работать при попытке изменить шаблон. Так что я знаю, что это тоже не было на 100%. Надеюсь, это будет иметь смысл, т. к. это не просто проясняет то, что я, возможно, не понимаю, и я объясню больше, если потребуется, буду признателен за любую помощь. :)

ИЗМЕНИТЬ

index.html

<!-- App references -->
<link href="css/ionic.css" rel="stylesheet" />
<link href="css/angular-chart.css" rel="stylesheet" />
<link href="css/index.css" rel="stylesheet" />

<script src="lib/ionic/ionic.bundle.js"></script>
<script src="lib/ngCordova/ng-cordova.js"></script> <!-- Must be after Ionic but before Cordova-->
<script src="cordova.js"></script>
<script src="scripts/index.js"></script>

<script src="lib/angular-cookies/angular-cookies.min.js"></script>
<script src="lib/angular-chart/Chart.min.js"></script>
<script src="lib/angular-chart/angular-chart.min.js"></script>
<script src="lib/angular-ios9-uiwebview.patch.js"></script>
<script src="lib/angular-filter/angular-filter.min.js"></script>
<script src="js/directives/favourite.js"></script>

<script src="js/controllers.js"></script>
<script src="js/controllers/login.js"></script>
<script src="js/controllers/sales.js"></script>
<script src="js/app.js"></script>

person MattVon    schedule 21.12.2015    source источник
comment
как вы включаете свои файлы javascript в свой основной файл html?   -  person Raphael Müller    schedule 21.12.2015
comment
@RaphaelMüller, обновил мой пост внизу, чтобы показать. Все, что есть в моем теге ‹head›.   -  person MattVon    schedule 21.12.2015


Ответы (5)


Вы снова и снова переопределяете свой модуль в каждом файле контроллера. Который удаляет старый зарегистрированный контроллер из этого модуля.

Вы уже определили этот модуль в файле /js/controllers.js.

angular.module('main.controllers', ['ionic', 'ngCordova']);

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

angular.module('main.controllers')
person Pankaj Parkar    schedule 21.12.2015
comment
но кто сказал, что login.js первый? если появится ananotercontroller.js, это будет первым, и определение должно быть перемещено - person Raphael Müller; 21.12.2015
comment
@RaphaelMüller Да .. Спасибо за внимание .. это было очень плохое предположение с моей стороны .. Теперь я обновил ответ - person Pankaj Parkar; 21.12.2015
comment
Итак, я следил за этими изменениями, и оба login.js и sales.js больше не переопределяются и повторно используют модуль controller.js. Однако я все еще получаю ту же ошибку angularJS? - person MattVon; 21.12.2015
comment
@MattVon, вы ссылались на этот файл сценария на index.html? - person Pankaj Parkar; 21.12.2015
comment
@PankajParkar, извиняюсь, я должен был добавить, что в моем исходном посте это то, что у меня есть. (обновлю основной пост) <script src="js/controllers.js"></script> <script src="js/controllers/login.js"></script> <script src="js/controllers/sales.js"></script> <script src="js/app.js"></script> - person MattVon; 21.12.2015
comment
Исправлено! У меня была небольшая опечатка где-то еще в моем коде, спасибо! - person MattVon; 21.12.2015
comment
@MattVon Рад помочь вам..Спасибо :)' - person Pankaj Parkar; 21.12.2015

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

модули.js:

angular.module('main', ['main.sales']);
angular.module('main.sales', []);

src/sales/scripts/sales-controller.js:

angular.module('main.sales').controller(function() {});

Если вы объединяете и минимизируете свои js-файлы с помощью grunt или gulp, вы всегда должны сначала явно включать modules.js, а затем вы можете включать остальные с помощью шаблона, такого как, например, «src/**/*.js».

Таким образом, модули всегда определяются до их использования. Если это не так, angular будет жаловаться на несуществующий модуль.

PS: лучше создавать функциональные модули (функции связанные с продажами в 1 модуле) вместо технических модулей (все контроллеры в 1 модуле)

person GDJ    schedule 21.12.2015

Вы объявляете модуль main.controllers дважды, по одному разу для каждого контроллера. Кроме того, не обязательно объявлять отдельный модуль для контроллеров, вы можете просто объявить контроллеры в своем основном модуле. Некоторые утверждают, что вы теряете возможность повторного использования — и они будут правы — но в зависимости от размера вашего проекта и того, насколько тесно ваши контроллеры связаны с вашим приложением (в 90% случаев ответ: очень ) можно и так. Поскольку вы, вероятно, только начинаете, попробуйте сделать что-то вроде этого:

js/app.js

angular.module('main', ['ionic', 'chart.js', 'ngCordova', 'ngIOS9UIWebViewPatch', 'angular.filter'])

.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
    $stateProvider

    .state('login', {
        cache: false,
        url: "/login",
        templateUrl: "templates/login.html",
        controller: "LoginCtrl"
    })

    .state('sales', {
        cache: false,
        url: "/sales",
        templateUrl: "templates/sales.html",
        controller: "SalesCtrl"
    })

    $urlRouterProvider.otherwise('/login')
    $ionicConfigProvider.views.swipeBackEnabled(false);
});

Обратите внимание, что я больше не завишу от main.controllers? Это потому, что в следующий раз я делаю это:

angular.module('main')
.controller("LoginCtrl", function ($scope, $state, $cordovaSQLite, $timeout,       $ionicPopup, $cordovaDevice, $ionicLoading, $cordovaKeyboard, $cordovaToast) {
$ionicLoading.show({
    template: 'Loading...'
});
// DO STUFF

И это:

angular.module('main')
.controller("SalesCtrl", function ($scope, $state, $http, $ionicLoading, $cordovaSQLite, $cordovaToast) {
$ionicLoading.show({
    template: 'Loading data...'
});
// DO STUFF

Различные контроллеры могут (и должны) быть объявлены каждый в отдельном файле, чтобы у вас была четкая структура. Возможно, было бы правильнее иметь отдельный модуль для контроллеров, и я боюсь, что мое мнение может быть непопулярным, но я не вижу смысла, тогда как я настоятельно рекомендую вам разделить ваши службы и ваши директивы на разные модули, поскольку гораздо более вероятно, что вы будете использовать их снова в других проектах.

person Gian Marco Toso    schedule 21.12.2015
comment
Я ценю ваше понимание, я обязательно буду иметь это в виду. Я проверил ваш подход и заменил «main.controllers» на «main» в моих файлах контроллеров и удалил «main.controllers» из файла app.js. Однако я все еще получаю ту же ошибку AngularJS, что и раньше. - person MattVon; 21.12.2015

Я предлагаю организовать код, разделив его на модуль, и внедрить его в файл app.js.

Это мой способ: https://mymai91.github.io/ionic/2016/07/01/ionic-structure-code-for-project.html

Демонстрация кода: https://github.com/mymai91/mymaiApp

person My Mai    schedule 01.07.2016

всем, кто смотрит на "решенный код"... Квадратные скобки во внутренних контроллерах должны быть удалены:

angular.module('main.controllers', [])

-->

angular.module('main.controllers')
person webmobileDev    schedule 22.08.2016