Reputation: 61
I'm following the AngularJS tutorial on its site, and at the moment my controller is as followed, and the page loads perfectly:
var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
});
As I was doing the "A Note on Minification" part of Step 5, I came up with this:
var phonecatApp = angular.module('phonecatApp', []);
function PhoneListCtrl($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}
//phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', PhoneListCtrl]);
The page loads just fine with the second code, where I commented the creation of controller from the module. My question is, what's the difference between declaring a controller from the module and defining a function
Upvotes: 1
Views: 224
Reputation:
There is no difference in the actual execution/behaviour, the second one is using something called a 'function constructor'. It is a common way of creating a class-like structure in javascript.
The first one under the hood will be doing the same thing it's just that angularJs' dependency injection model works with strings so this is easier to read.
Upvotes: 4
Reputation: 18103
Check out Todd Motto's style guide for angular: http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/
Defining your controllers as a function expressions is important to keep your code DRY and allow for named stack traces:
This is okay:
function PhoneListCtrl($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}
The issue is that this puts the function in the global scope; ohhh nooo. The solution is to wrap the declaration in an IIFE. This allows you to keep the best practice of defining your functions and to not pollute the global scope.
Here's an example:
(function () {
angular.module('app', []);
// MainCtrl.js
function MainCtrl () {
}
angular
.module('app')
.controller('MainCtrl', MainCtrl);
// AnotherCtrl.js
function AnotherCtrl () {
}
angular
.module('app')
.controller('AnotherCtrl', AnotherCtrl);
// and so on...
})();
Upvotes: 1
Reputation: 22181
Like this:
function PhoneListCtrl($scope, $http) {
your function would be declared in the global
scope.
And we know that is clearly bad to pollute the global scope since it may lead to variable/function conflict.
By wrapping it inside a controller, you isolate the scope.
Upvotes: 0
Reputation: 691765
Declaring a global function, AFAIK was possible in order to simplify simple demos and get up to speed quickly. In latest versions of Angular, it's not supported by default anymore (see https://github.com/angular/angular.js/commit/3f2232b5a181512fac23775b1df4a6ebda67d018).
It's bad practice anyway to pollute the global namespace with lots of functions.
Upvotes: 1