How to create separate AngularJS controller files?

2019-01-01 08:29发布

问题:

I have all of my AngularJS controllers in one file, controllers.js. This file is structured as follows:

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

What I\'d like to do is put Ctrl1 and Ctrl2 into separate files. I would then include both files in my index.html, but how should that be structured? I tried doing some thing like this and it throws an error in the web browser console saying it can\'t find my controllers. Any hints?

I searched StackOverflow and found this similar question - however, this syntax is using a different framework (CoffeeScript) on top of Angular, and so I haven\'t been able to follow.


AngularJS: How do I create controllers in multiple files

回答1:

File one:

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

File two:

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

}]);

File three:

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

}]);

Include in that order. I recommend 3 files so the module declaration is on its own.


As for folder structure there are many many many opinions on the subject, but these two are pretty good

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

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



回答2:

Using the angular.module API with an array at the end will tell angular to create a new module:

myApp.js

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

Using it without the array is actually a getter function. So to seperate your controllers, you can do:

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

During your javascript imports, just make sure myApp.js is after AngularJS but before any controllers / services / etc...otherwise angular won\'t be able to initialize your controllers.



回答3:

Although both answers are technically correct, I want to introduce a different syntax choice for this answer. This imho makes it easier to read what\'s going on with injection, differentiate between etc.

File One

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

File Two

// 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
}

File Three

// 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
}


回答4:

What about this solution? Modules and Controllers in Files (at the end of the page) It works with multiple controllers, directives and so on:

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 has also a Best Practice Recommendations for Angular App Structure I really like to group by context. Not all the html in one folder, but for example all files for login (html, css, app.js,controller.js and so on). So if I work on a module, all the directives are easier to find.



回答5:

For brevity, here\'s an ES2015 sample that doesn\'t rely on global variables

// 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)


回答6:

Not so graceful, but the very much simple in implementation solution - using global variable.

In the \"first\" file:


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

in the \"second\" , \"third\", etc:


myApp.controller(\'MyController\', function($scope) {
    .... 
    });