Is there an established convention regarding declaration of controllers? (Or any form of module-level configuration).
I have observed two different approaches in use:
var shoppingCartModule = angular.module('ShoppingCart',[])
shoppingCartModule.controller('CheckoutCtrl', function($scope) { ... });
vs
angular.module('ShoppingCart').controller('CheckoutCtrl', function($scope) { ... });
Are there any benefits between the two approaches? Also, is there a preferred (or emerging) convention?
I'm specifically interested in benefits for non-trivial apps with many modules, where declarations of controllers and modules may span many files.
Personally I do the following (reasons after):
angular.module('myApp', []);
angular.module('myApp').controller('myController', ['$dependency', 'anotherDependency',
function($dependency, anotherDependency) {
...
}
]);
Reasons:
I try and avoid the global scope
Redundantly declaring dependencies with string equivalents allows you to safely minify your code
It's consistent, clean and the whole story is there. Eg. with app.something you don't know what app is, with `angular.module('myApp').something' it's pretty obvious what that is.
Edit: Just remembered a cool video I saw on this very topic a while ago - http://www.egghead.io/video/tTihyXaz4Bo. If you haven't checked out John's site, I highly recommend it. I was so impressed with his videos I donated, and you should too!
Personally, I find it be a little bit cleaner this way:
angular.
module('myApp').
controller('myController', ['$dependency', 'anotherDependency', myAppController]);
function myAppController($dependency, anotherDependency) {
...
}
Or, even more better:
var Controllers = {};
Controllers .someController = function myAppController($dependency, anotherDependency) {
...
}
angular.
module('myApp').
controller('myController', ['$dependency', 'anotherDependency', Controllers .someController]);
Related
I went deep into investigating of modern approaches and stuck with a problem.
One approach is to split application modules depending on purpose:
angular.module('controllers', [])
angular.module('directives', [])
angular.module('services', [])
Another approach is to split modules by feature
angular.module('page.user', [])
.controller()
.service()
I do like the second one and believe that is the most efficient one. BUT, what about reusable services? Here is a brief example I took from my head:
angular
.module('myApp') // myApp refers to the main app module
.service('userService', function($http) {
let self = this;
self.getUser = function(id) {
return $http.get('api/user/' + id)
.then(functions() {
// some important logic hoes here
})
}
})
So I have a getUser method, that contains some specific business logic.
I do not want copy the same method to every new feature-module because DRY. I want every feature, that need getUser ,method to refer userService, so in this case I would need to put the service into main app module which will bootstrap all other feature-modules as well, or I need to create a modules specially for shared services and now we at the first on purpose approach.
So the question is more like how to stick to the second approach and keep everything well organized with DRY principle. Thanks
I am New to learn a Angular Javascript. Can anyone gave me the knowledge of Dependency Injection with Its Demo Example. So That I did learn from there. No Good and clear link I have found from Googling.
Dependency
injection is a design pattern that allows for the removal of hard-coded dependencies, thus making
it possible to remove or change them at run time.
In general, there are only three ways an object can get a hold of its dependencies:
We can create it internally to the dependent.
We can look it up or refer to it as a global variable.
We can pass it in where it’s needed.
With dependency injection, we’re tackling the third way.We dont follow the first 2 ways because a good programmer never dirty the global scope and it will be difficult for the isolation of the code.
This ability to modify dependencies at run time allows us to create isolated environments that are
ideal for testing. We can replace real objects in production environments with mocked ones for
testing environments.
For instance,let us consider this simple app that declares a single module and a single controller, like so:
angular.module('myApp', [])
.factory('greeter', function() {
return {
greet: function(msg) { alert(msg); }
}
})
.controller('MyController',
function($scope, greeter) {
$scope.sayHello = function() {
greeter.greet("Hello!");
};
});
At run time, when Angular instantiates the instance of our module, it looks up the greeter and simply
passes it in naturally.
Nowhere in the above example did we describe how to find the greeter; it simply works, as the
injector takes care of finding and loading it for us.
For further reference please visit Angularjs Modularization and Dependency injection which can help you get a better understanding.
I started learning angularjs and I see 2 types of module uses and I cant understand when to use this and when this:
example1:
var app = angular.module('app', []);
app.factory('Comment', function($http) {
}
app.controller('mainController', function($scope, $http, Comment) {
}
or
example2:
angular.module('commentService', [])
.factory('Comment', function($http) {
}
angular.module('mainCtrl', [])
.controller('mainController', function($scope, $http, Comment) {
}
var app = angular.module('app', ['commentService','mainCtrl']);
sometimes I see module declarion in each file(services factory controllers and so on)
and sometimes I see using the app module in those files, what is the right way? and why both of them works?
First and foremost, if you're concerned about app organization, read the discussion on the yeoman-generator-angular issue board from about a year ago. There's way more wisdom there than you could feasibly expect to get in a SO answer.That said, I'll try to provide an answer that's more pertinent to your specific concern, and (marginally) more concise.
DO NOT make a module for a single controller like angular.module('MainCtrl',[]).controller('MainCtrl'), or even a set of controllers who are only related in that they are all controllers:
angular.module('appCtrl', [])
.controller('appleController', function ($scope) {})
.controller('orangeController', function ($scope) {})
.controller('unicornController', function ($scope) {})
;
Why is this a bad idea? First, by definition, it's categorical, not modular; modules are groupings of system components which are related topically, not conceptually. When you're building a car, you don't put in all of the nuts and bolts at once. You put in the nuts and bolts that hold together the module that you're building. Controllers are like nuts and bolts. An engine is like a module.
Second, now you have to inject the appCtrl module anywhere that you want access to a controller. That's just a mess for developers to have to deal with; they're always digging through the code trying to find "whatever that module with that one thing in it" was, or they'll just repeat code all over the place.
Dependency Injection in AngularJS is less a rule than a (clever and awesome) string manipulation hack, and JavaScript has no "namespacing" system in the classical sense. Creating modules like app.products or app.cart is more for the developer's convenience and/or controlling the release cycle than making the program "work".
For these and other reasons, I caution developers against "Premature Modularization". If you're writing something app-specific---that is, you won't be reusing it right now in another app---why not just attach it to your app module? Then you have access to it anywhere in your app that you want it. (There are of course complexities that might cause you to change this, but if/when those do arise that's when you modularize).
Structure your directories by feature (Angular conventions do condone BDD, after all):
|-app/
|-|-cart/
|-|-|-CartItemsModel.js
|-|-|-OrderRepository.js
|-|-|-cart.html
|-|-|-add-item-modal/
|-##some more cart stuff
|-|-checkout/
|-|-|-confirmation/
|-|-|-|-confirmation.html
|-|-|-|-confirmation.less
If you're writing feature files or getting acceptance criteria from your employer, you can even model your directory structure directly after those features or requirement sets. That makes everything smooth from defining the scope of an iteration through documentation through revisiting code at a later time.
Both example work. But for instance with the example 2, this syntax can be used for separation of concern. You may need a module that is responsible for providing services which gives you function for Rest calls. Or another module that package some directives.
It's generally considered good practice to segregate your modules into different files. This will ensure that you are practicing good code control, and gives your code a greater degree of portability and debug-ability. Instead of declaring modules in the same file, declare them in different files with their module name.
It's good practice to segregate your files based on their module-controller relationship -- that is, each controller should have its own file, like this:
\scripts\controllers\
- - main.js
- - comments.js
Then, inside your main.js file, you'll start off with the controller declaration:
//main.js
angular.module('app')
.controller('MainController', function ($scope, $http) {
// Controller-scope stuff here
});
Finally, inside your comments.js file:
angular.module('app')
.controller('CommentsController', function($scope, $http, $routeParams) {
// Comment controller code
});
One way to help with organization right off the bat is to organize your files is with a seed template, like Angular Seed.
Just remember that you want to keep your module('app').controller('whatever') inside whatever.js, and any other .factory('forWhatever') (like in your example) should be contained with that parent .controller('whatever') inside the whatever.js file.
In most demos below method is given
First Method:
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
Second Method:
app.controller("MyController",funciton( $scope ){
$scope.someValue = "All your base are belong to us!";
});
What are the pros and cons of using either method?
I'll try to give a quick summary each options pros and cons.
1) The following version is often used in examples around the web because it's easy to write. I wouldn't recommend it in real code however, for two reasons. First of all it can break horribly if you minify your code (and you should), secondly you are littering with globals which is generally bad form and encourages sloppy dependencies that are hard to test.
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
2) The second version you wrote is better. It contains the function on the app which is good, but it can still break from some minifiers.
app.controller("MyController",function( $scope ){
$scope.someValue = "All your base are belong to us!";
});
3) To make it better, lets do this instead. Note that the function is now inside a list with its dependencies. This "double" naming of the dependencies helps angular keep track of things in minified code.
app.controller("MyController", ['$scope', function( $scope ){
$scope.someValue = "All your base are belong to us!";
}]);
4) You can also inject your dependencies after your controller, something like this. This should also be safe from minifiers as far as I know (I haven't used this version myself).
app.controller("MyController",function( $scope ){
$scope.someValue = "All your base are belong to us!";
}).$inject = ['$scope'];
So 3 and 4 are the best ones. They survive minifying and they allow you to easily mock out any dependency when writing tests. As far as I know the difference between 3 and 4 is cosmetic so both should work equally fine. I personally use 3, I think it looks slightly nicer :)
I would highly recommend the second one.
The reason behind this is minification. Angular will try to match the controller's name you call in the templates via ng-controller, e.g.:
<div ng-controller="Controller">
<!-- [...] -->
</div>
Suppose you have a controller like this:
function Controller($scope) {};
and minify it (with some minifiers), you'll get an output like this:
function c(s) {};
Quick EDIT: I checked it with uglify - it will preserve your function name (and you'll be fine), I used a maven based minifier in a project of mine, which actually mangled the method names (I guess I have to replace it)
Your app might just break from that.
Therefore it is recommended to use strings as identifiers for controllers (and injections, etc.) like this:
var app = angular.module("module", []);
app.controller("Controller", ['$scope', function(scope) {
}]);
This will stop a minifier from breaking the app. The reason to put injections like this is as follows:
var app = angular.module('module',[]);
function Ctrl($scope, $location) {
$scope.test = 42;
};
will get minified to (by UglifyJS):
function Ctrl(a){a.test=2}var app=angular.module("module",[])
and Angular will not know that you need the $scope here.
If minification does not matter to you, you can use either one, as the question really just breaks down to maintainability and readability. Also, if you have multiple modules with controllers, the second one will not get you into trouble.
The difference is that the second version defines the controller in your app space. Thus the app.controller call. Difference is that afaik you can only use the controller inside of an ng-app="yourApp" instead of everywhere on the site.
Personally, I like more the 2nd method, because it is easier to review the code and it is more maintainable, those are just my thoughts.But with 1st method you can put it as a controller in other apps.
Here is what I found from
http://www.bennadel.com/blog/2421-Creating-AngularJS-Controllers-With-Instance-Methods.htm
In most AngularJS demos, you will see Controllers being defined as free-standing JavaScript functions:
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
These functions are then referenced in the View using the ngController directive:
<div ng-controller="MyCtrl">
{{ someValue }}
</div>
NOTE: You should never ever abbreviate "Controller" as "Ctrl". I am only doing that here because this it is what you will typically see in a demo. You should try to avoid abbreviations as much as humanly possible when naming things in programming.
The expression used to define the ngController directive is the name of the Controller in your dependency injection (DI) framework. In an AngularJS application, the dependency injection framework is provided directly by AngularJS. This means that, rather than using a free-standing function, we can use the AngularJS controller() method to define our Controllers:
// Define "MyController" for the Dependency Injection framework
// being used by our application.
app.controller(
"MyController",
funciton( $scope ){
$scope.someValue = "All your base are belong to us!";
}
);
Here, we are defining the controller as an identifier - MyController - and a constructor function. And, once we can do this, we can get much more fine-tuned in how we actually define our constructor function.
I've seen 2 types of controllers definition:
angular.module('myApp.controllers',[])
.controller('MainCtrl', ['$scope'], function($scope){
//controller code
}
And a simple:
function MainCtrl($scope) {
//controller code
}
What's the different? Which one is the preferred one?
The difference is that the first is a controller inside the module.
The second method is a controller on the global ( on the Window object! ).
Like you would have heard already, polluting the global object is a bad idea. Hence, the second method is not preferred (But is used for quick prototyping to show off a feature easily and is easier to type. So this one is used in pretty much all examples.)
The first way, i.e
angular.module('myApp.controllers',[])
.controller('MainCtrl', ['$scope'], function($scope){
//controller code
}
is the preferred way and should be used in all for production applications.