I have two modules as follows.
var module1 = angular.module('myApp',['ngAnimate','ngTouch']
.controller('MainCtrl', function ($scope)){
});
var module2 = angular.module('myApp',[]);
module2.controller('NameCtrl',function($scope)){
});
And Html here
<body ng-app='myApp'>
<div ng-controller='MainCtrl'> //Code here</div>
<div ng-controller='NameCtrl'>//Code here</div>
</body>
But this throws error like this.
'NameCtrl' is not existing
Please let me know how to fix this.
Thanks in advance
Proper structure would look like this...
var myApp = angular.module('myApp', ['ngAnimate','ngTouch']);
myApp.controller('MainCtrl', function($scope){
});
myApp.controller('NameCtrl', function($scope){
});
Remember
Each module is like a separate app. Each module has to be a unique name, each module can have things like their own configuration, controllers, services etc.
You don't need 2 modules.
module1.controller('NameCtrl',function($scope)){
});
is what you want
You are declaring two different modules with the same name. You can't do it.
the angular.module method is a jQuery-like getter and setter. If you call'it with just one parameter it works as a getter, if you call it with two or more parameters, then, it works as a setter.
So, if you need (as seems) to register just another recipe (controller, service, ecc.) but not a new module, you need to do angular.module('ngApp').controller.
Otherwise, if you need for a new module, you need to assign it a different name and bootstrap it manually via angular.bootstrap
You don't need to create two modules.
You could implement what you need as follows.
var myComponent = angular.module('myComponent',[]);
myComponent.controller('MainCtrl',function($scope)){
};
myComponent.controller('NameCtrl',function($scope)){
};
This is one you looking for ?
var modules = angular.module('myApp',['ngAnimate','ngTouch']
.controller('MainCtrl', function ($scope)){
});
modules.controller('NameCtrl',function($scope)){
});
You cannot have two modules with the same name.
In case your project is structured in a way, that truly prevents you from using just one module, you could to this.
var module2 = angular.module('myModule2',[]);
module2.controller('NameCtrl',function($scope) {...});
var module1 = angular.module('myApp',['ngAnimate','ngTouch', 'myModule2']
.controller('MainCtrl', function($scope){...});
To decompose your application into multiple modules you need to name the app and the component(s) something different and make your app depend on your component(s).
var myComponent = angular.module('myComponent',[]);
myComponent.controller('NameCtrl',function($scope)){});
var anotherComponent = angular.module('anotherComponent',[]);
anotherComponent.controller('NameCtrl',function($scope)){});
var myApp = angular.module('myApp',['ngAnimate','ngTouch', 'myComponent', 'anotherComponent']);
myApp.controller('MainCtrl', function ($scope)){});
That's a bit confusing, because, according to docs, by declaring module2 you are overwriting already existing myApp module, which should lead to MainCtrl to be not existing one. Consider trying what Wainage suggested, or, if you really need two separate modules, to do something like this:
var module1 = angular.module('myApp.module1', []);
module1.controller('NameCtrl',function($scope){
$scope.value = 'Name controller value';
});
var myApp = angular.module('myApp', [/*Other dependencies*/'myApp.module1']);
myApp.controller('MainCtrl', function ($scope){
$scope.value = 'Main value';
});
You can't declare two module with same name. you can use different controller, service, directive, factory etc in same module so you may no need to use different module for simple app.
If need different controller in same module then use like
var myModule = angular.module('myApp',['ngAnimate','ngTouch']);
myModule .controller('MainCtrl', function ($scope){
//code
});
myModule .controller('NameCtrl', function($scope){
//code
});
If need different module then need different name. Can use different module for those application that are module based application.
Related
I have a simple example function checkIfValueIsGreaterThan0
If I have an ng-click function I can use it like this:
<div ng-click="checkIfValueIsGreaterThan0()"></div>
But I then need this function declared in my $scope. Is there a way to add this to a global library that can be used across my application and be able to inject that library and have it work from my view without having to declare it explicitly like so in my controller?
$scope.checkIfValueIsGreaterThan0 = myLibrary.checkIfValueIsGreaterThan0
In your app bootstrap, in a run or config block, set it on $rootScope (which itself should be injected):
$rootScope.checkIfValueIsGreaterThan0 = myLibrary.checkIfValueIsGreaterThan0;
As $rootScope is the parent of all scopes within your application, you will be able to use checkIfValueIsGreaterThan0() in any template or $scope.checkIfValueIsGreaterThan0() in any controller..
Yes it is most certainly possble, u can make a factory service out of it and use it across ur app. You may need to pass $scope or $http service to ur factory but it depends on what are u trying to accomplish. In case if u do then u can do it like i did it in the controller below
var app = angular.module( 'myApp' ,[]);
app.factory(' checkIfValueIsGreaterThan0', function()
{
var checkIfValueIsGreaterThan0 = {};
checkIfValueIsGreaterThan0.test = function()
{
// Do ur stuff here and return it
}
return checkIfValueIsGreaterThan0;
});
When u want to use this factory simply inject it into ur controller and call it, and as u said u wana assign it to the $scope u can do that as following.
app.controller( 'myCtrl' , ['$scope', 'checkIfValueIsGreaterThan0', function($scope, checkIfValueIsGreaterThan0)
{
$scope.whatever = checkIfValueIsGreaterThan0.test();
}]);
I hope u'll get the idea, If there is any typo error i'm sorry for that cuz i'm tryping this from mobile fone.
Well I have seen couple of questions in StackOverFlow related to this but couldn't find proper answer.
Say in my app.js file I have defined a constants object which basically has controllers names. As I use "ui-router" I want to attach Controllers to views on state change.
app.js
var app = angular.module('myApp', ['ui.router']);
app.constant('CONTROLLER', {
ONE: 'ControllerOne',
TWO: 'ControllerTwo'
});
Now I want to use those constants to define Controller names in other file, say controller.js. Illustrating couple of ways which I tried but dint work for me.
controller.js
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', function ($scope, myFactory) {
$scope.result = myFactory.someAPI();
}]);
ERROR -> Uncaught ReferenceError: CONTROLLER is not defined
Even I tried injecting that constant module in Controller which gave same error.
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', 'CONTROLLER', function ($scope, myFactory, CONTROLLER) {
$scope.result = myFactory.someAPI();
}]);
I know that second way is wrong. As I define controller names in my main app.js file and use those constants to attach controllers to views during state change.
I want reuse those constants to define controllers names too.
I may be doing something wrong. Any suggestions ?
Your code shows that you have correctly injected the CONTROLLER constant into the controller constructor function.
var app = angular.module('myApp', ['CONTROLLER']);
app.controller(CONTROLLER.ONE, ['$scope', 'myFactory', 'CONTROLLER', function ($scope, myFactory, CONTROLLER) {
// use constant here
}]);
That being said you can only access the constant except from within the controller function itself. The names of controllers, services, factories etc must be accessible strings, which is not the case until the constant has been injected.
You could use a plain old JavaScript object outside angular to define the names.
var CONTROLLER = {
ONE: 'ControllerOne',
TWO: 'ControllerTwo'
});
I can only guess that you are trying to do this because the controller or directive you are writing will be referenced/used at multiple points throughout your html.
As an example, we have this index.html code:
<!DOCTYPE html>
<html ng-app="sample">
<head>
...
</head>
<body>
<div ng-controller="myController">
...
<script src="js/modules/app.js"></script>
</div>
</body>
</html>
and in app.js we have a module and a controller:
var app = angular.module('sample', []);
// controller here
So my question is that, I have seen controllers defined in two types, as a controller, and as a plain function:
app.controller('myController', function(args){
...
});
or
var myController = function(args){
...
};
Which one should be used and why? I have mostly seen the first one used in Angular-based code, but even in tutorials I have come across the second. I personally don't use the second, as I have read it 'pollutes the global namespace'.
Another question I have is that I have seen this kind of usage for a controller:
app.controller('myController', ['$scope', '$http', function($scope, $http) {
...
}]);
Why do we need the array? Can't we make do with just the arguments?
According to the Angular the array annotation based dependency injection or definition is the preferred way:
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
See Inline Array Annotation
This is the preferred way to annotate application components. This is
how the examples in the documentation are written.
While at the other hand, the simplest way to get hold of the dependencies is to assume that the function parameter names are the names of the dependencies (which is not preferred for like production app).
someModule.controller('MyController', function($scope, greeter) {
// ...
});
The Angular can infer the names of the services to inject by examining the function declaration and extracting the parameter names. In the above example, $scope and greeter are two services which need to be injected into the function.
However this method will not work with JavaScript minifiers/obfuscators because of how they rename parameters.
The resulting code after minification will be like this:
someModule.controller('MyController', function(a, b) {
// ...
});
So now, the Angular does not know what is the dependency a & b while if you use the array annotation based, the output will be:
someModule.controller('MyController',['$scope','greeter', function(a,b) {
// ...
}]);
So, now Angular can map a with $scope and b with greeter and will be able to resolve the dependency.
app.controller('myController', ['$scope', '$http', function($scope, $http) {
This is done to prevent JS minifiers from breaking your code, because angular relies on names for dependency resolutions.
As for the two styles of controller
app.controller('myController', function(args){
...
});
vs
var myController = function(args){
...
};
app.controller('myController', myController);
It's a matter of personal taste. There's no functional difference.
The first question is mostly about style, since both methods are correct.
There might be arguments about both ways of defining controllers and other Angular modules. But as it is with every language in Software Development: Find a coding style and stick to it. Inconsistencies are the real problem.
Here's a good style guide to stick to: https://github.com/johnpapa/angular-styleguide
The second question has to do with minification. Please read this article: http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/
Syntax for Controllers
The most preferred way for Angular 1.x version is to use Controller As syntax. Please see code below:
(function () {
'use strict';
angular.module('app.controllers')
.controller('HeadController', HeadController);
HeadController.$inject = ['someService'];
function HeadController(someService) {
/* jshint validthis: true */
var vm = this;
vm.logout = action;
function action() {
someService.doSomeAction();
}
}
})();
In your html it will be used like this:
<div ng-controller="HeadController as vm">
<a href ng-click="vm.logout();" id="item-btn-logout"><i class="icon-off">
</div>
I prefer this syntax. This will let you not to use scope in your views.
Take a look at John Papa AngularJS guide - it is good!
If you are still thinking that it's too complicated and you ain't gonna need it - refer to this article that explains how to avoid Scope Soup in Angular.
Why do we need the array?
Array with plain text is used during injection of dependencies. This will let you minify your code easily and not to lose dependency names during initialization process. If you are not going to do this and minify your code - you are risking that your code won't work.
I'm trying to use lodash use it at ng-repeat directives, in this way:
<div ng-controller="GridController" ng-repeat="n in _.range(5)">
<div>Hello {{n}}</div>
</div>
Being GridController:
IndexModule.controller('GridController', function () {
this._ = _
})
However is not working and so, nothing being repeated. If I change the directive to ng-repeat="i in [1,2,3,4,5]" it'll work.
lodash is already included via <script> at <header> before angular. How can I make it work?
I prefer to introduce '_' globally and injectable for tests, see my answer to this question
Use underscore inside controllers
var myapp = angular.module('myApp', [])
// allow DI for use in controllers, unit tests
.constant('_', window._)
// use in views, ng-repeat="x in _.range(3)"
.run(function ($rootScope) {
$rootScope._ = window._;
});
I just wanted to add some clarification to #beret's and #wires's answer. They definitely helped and got the jist of it but getting the whole process in order might suit someone. This is how I set up my angular environment with lodash and got it working with yeoman gulp-angular to serve properly
bower install lodash --save (This adds to bower and a saves to bower json)
modify bower json to have lodash load before angular does. (This helps if you're using gulp inject and don't want to manually put it into index.html. otherwise put it into the index.html before the angular link)
Make a new constant per #wires's direction.
'use strict';
angular.module('stackSample')
// lodash support
.constant('_', window._);
Inject into any angular service, filter, or controller as you would anything else:
.filter('coffeeFilter', ['_', function(_) {...}]);
To throw it into some angular html view just inject it into the controller and assign a scope variable to it:
.controller('SnesController', function ($scope, _) {
$scope._ = _;
})
Hope this helps someone set up their site. :)
ng-repeat requires an Angular expression, which has access to Angular scope variables. So instead assigning _ to this, assign it to the $scope object you inject into the controller:
IndexModule.controller('GridController', function ($scope) {
$scope._ = _;
})
Demo
I am not sure what version of Angular you are using. Looks like you should have just used the 'Controller as' syntax when you use 'this' to access variables in the dom.
Here is the solution with this and not using scope.
http://plnkr.co/edit/9IybWRrBhlgQAOdAc6fs?p=info
<body ng-app="myApp" ng-controller="GridController as grid">
<div ng-repeat="n in grid._.range(5)">
<div>Hello {{n}}</div>
</div>
</body>
Suppose I want to make this a variable a constant to be shared among controllers in Angularjs;
$webroot = "localhost/webroot/app"
After some investigation, it seems services are the way to do. But what is the best way? Do I use a factory, service, value or something else?
The services.js from angularjs-master-seed is below;
angular.module('myApp.services', []).value('version', '0.1');
How do I modify it to have a constant $webroot that is sharable among controllers?
Can I do the following?
angular.module('myApp.services', [])
.value('version', '0.1')
.constant('webroot','localhost/webroot/app');
If it is ok, how do I call it in the controller?
Whats happens when you want more constants? How about adding a config object that you can inject wherever needed. As its a single file it's also much easier to have dev.config and prod.config files that can be swapped in and out at build time.
app.factory('Config', function(){
return{
webRoot: "localhost/webroot/app",
moreSettings: "abc"
};
});
If your variable have a constant value or is set once value is the right choice.
You can define it like this:
app = angular.module('myApp', []);
app.value('$webroot', 'localhost/webroot/app');
Now you can inject the service to your controller and use it:
app.controller('myController', ['$scope', '$webroot', function($scope, $webroot) {
$scope.webroot = $webroot;
}]);
Edit #1
To fit your updated question: You can use a constant the same way as a value:
app = angular.module('myApp', []);
app.constant('$webroot', 'localhost/webroot/app');
app.controller('myController', ['$scope', '$webroot', function($scope, $webroot) {
$scope.webroot = $webroot;
}]);