Как создать отдельные файлы контроллера AngularJS?

301

У меня есть все мои контроллеры AngularJS в одном файле, controllers.js. Этот файл структурирован следующим образом:

angular.module('myApp.controllers', [])
  .controller('Ctrl1', ['$scope', '$http', function($scope, $http) {    
  }])
  .controller('Ctrl2', ['$scope', '$http', function($scope, $http) }
  }])

Что бы я хотел сделать, это добавить Ctrl1 и Ctrl2 в отдельные файлы. Затем я бы включил оба файла в свой index.html, но как это должно быть структурировано? Я попытался сделать что-то вроде этого, и это порождает ошибку в консоли веб-браузера, говорящей, что он не может найти мои контроллеры. Любые подсказки?

Я искал StackOverflow и нашел этот похожий вопрос - однако этот синтаксис использует другую структуру (CoffeeScript) поверх Angular, и поэтому я не смог следовать.


AngularJS: Как создать контроллеры в нескольких файлах

Теги:
controller

6 ответов

401
Лучший ответ

Файл один:

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

Файл два:

angular.module('myApp.controllers').controller('Ctrl1', ['$scope', '$http', function($scope, $http){

}]);

Файл три:

angular.module('myApp.controllers').controller('Ctrl2', ['$scope', '$http', function($scope, $http){

}]);

Включить в этом порядке. Я рекомендую 3 файла, поэтому декларация модуля сама по себе.


Что касается структуры папок, то существует много мнений по этому вопросу, но эти два довольно хороши

https://github.com/angular/angular-seed

http://briantford.com/blog/huuuuuge-angular-apps.html

  • 1
    Если ОП указывает на путаницу в синтаксисе CoffeeScript, может быть, лучше не использовать его в своем ответе?
  • 0
    @ Андрей, готово. Обновлено до прямой JS.
Показать ещё 24 комментария
180

Используя angular.module API с массивом в конце, скажем angular создать новый модуль:

myApp.js

// It is like saying "create a new module"
angular.module('myApp.controllers', []); // Notice the empty array at the end here

Использование этого без массива на самом деле является функцией getter. Поэтому, чтобы разделить ваши контроллеры, вы можете:

Ctrl1.js

// It is just like saying "get this module and create a controller"
angular.module('myApp.controllers').controller('Ctrlr1', ['$scope', '$http', function($scope, $http) {}]);

Ctrl2.js

angular.module('myApp.controllers').controller('Ctrlr2', ['$scope', '$http', function($scope, $http) {}]);

Во время импорта javascript просто убедитесь, что myApp.js находится после AngularJS, но перед любыми контроллерами/службами/etc... иначе angular не сможет инициализировать ваши контроллеры.

  • 0
    где я должен написать свои зависимости. var myapp = angular.module ('demo', ['ngRoute', 'ngCookies', 'ui.bootstrap', 'nvd3ChartDirectives', 'ui-rangeSlider', 'textAngular', 'angularTreeview']);
  • 0
    @vipin точно так же, как вы набрали, но убедитесь, что он выше любых контроллеров, сервисов и т. д. Технически вам не нужно объявлять var myapp = ...; потому что угловой будет хранить его для вас.
Показать ещё 2 комментария
48

Хотя оба ответа являются технически правильными, я хочу представить другой синтаксический выбор для этого ответа. Это imho облегчает чтение того, что происходит с инъекцией, различать и т.д.

Файл One

// Create the module that deals with controllers
angular.module('myApp.controllers', []);

Файл 2

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl1
// to the module we got in the line above
.controller('Ctrl1', Ctrl1);

// Inject my dependencies
Ctrl1.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl1($scope, $http) {
  // Logic here
}

Файл три

// Here we get the module we created in file one
angular.module('myApp.controllers')

// We are adding a function called Ctrl2
// to the module we got in the line above
.controller('Ctrl2', Ctrl2);

// Inject my dependencies
Ctrl2.$inject = ['$scope', '$http'];

// Now create our controller function with all necessary logic
function Ctrl2($scope, $http) {
  // Logic here
}
  • 0
    Интересно, что это мешает мне перейти на несколько файлов для регистрации контроллера
  • 4
    Я вижу много такого кодирования. В чем преимущество? иметь $ inject и функцию отдельно.
Показать ещё 3 комментария
14

Как насчет этого решения? Модули и контроллеры в файлах (в конце страницы) Он работает с несколькими контроллерами, директивами и т.д.:

app.js

var app = angular.module("myApp", ['deps']);

myCtrl.js

app.controller("myCtrl", function($scope) { ..});

HTML

<script src="app.js"></script>
<script src="myCtrl.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

В Google также есть Рекомендации по лучшей практике для Angular Структура приложения Мне очень нравится группироваться по контексту. Не все html в одной папке, но, например, все файлы для входа (html, css, app.js, controller.js и т.д.). Поэтому, если я работаю над модулем, все директивы легче найти.

1

Для краткости здесь пример ES2015, который не полагается на глобальные переменные

// controllers/example-controller.js

export const ExampleControllerName = "ExampleController"
export const ExampleController = ($scope) => {
  // something... 
}

// controllers/another-controller.js

export const AnotherControllerName = "AnotherController"
export const AnotherController = ($scope) => {
  // functionality... 
}

// app.js

import angular from "angular";

import {
  ExampleControllerName,
  ExampleController
} = "./controllers/example-controller";

import {
  AnotherControllerName,
  AnotherController
} = "./controllers/another-controller";

angular.module("myApp", [/* deps */])
  .controller(ExampleControllerName, ExampleController)
  .controller(AnotherControllerName, AnotherController)
  • 1
    Вы можете сэкономить немного времени, если используете именованные функции ... у них есть удобное name свойства ... так что вы можете просто использовать ExampleCtrl.name вместо dupl .. повторить его.
  • 0
    @AnttiPihlaja отличная идея! Редактирование приветствуется!
-2

Не так изящно, но очень просто в решении для реализации - с использованием глобальной переменной.

В "первом" файле:


window.myApp = angular.module("myApp", [])
....

в "втором", "третьем" и т.д.:


myApp.controller('MyController', function($scope) {
    .... 
    }); 
  • 0
    я использую этот код, но все еще не могу загрузить свой контроллер? это выдает ошибку: Ошибка: [ng: areq] Аргумент 'ProductCtrl' не является функцией, получил неопределенное значение.
  • 7
    это действительно плохая практика
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню