angular force me to make variables on window - javascript

I want to follow angularjs recommendation (http://docs.angularjs.org/guide/module):
While the example above is simple, it will not scale to large
applications. Instead we recommend that you break your application to
multiple modules like this:
A service module, for service declaration A directive module, for
directive declaration A filter module, for filter declaration And an
application level module which depends on the above modules, and which
has initialization code.
So I've created services.js file that only contains:
window.myservices = angular.module('services', []);
And then I added a few services where each service file starts with:
window.myservices.factory('service1', function() {
....
});
I made the same for filters.js and directives.js.
In my app.js file I made:
window.App = angular.module('app', ['services', 'filters', 'directives']).
// run \ config \ whatever
How can I do it without making variables on window?

There's no need for globals at all:
// Define your services
angular.module('services', [])
.factory('service1', function(){})
.factory('service2', function(){});
// Define you main app module and specify the dependencies
angular.module('MyApp', ['services']);

As Stewie said, you can use angular.modue('service',[]);
However you only need to do this in the first loaded file, like so:
file1.js
var mod = angular.module('service',['dependancy']);
file2.js
var mod = angular.module('service');
index.html
<script src="/scripts/file1.js"></script>
<script src="/scripts/file2.js"></script>
Another option is to use namespaces...
file1.js
var mod = angular.module('service.part1',[]);
file2.js
var mod = angular.module('service.part2',[]);
main.js
var mod = angular.moduel('service', ['service.part1','service.part2']);
EDIT (plunker):
http://plnkr.co/edit/i75A5CQeSptQjaxvR8qi?p=preview

Related

Why controllers is being created 2 times in my AngularJS + RequireJS application?

I am creating small application called puzometr. It is for educational needs only. I want to create this application using AngularJS. Also, I want to use RequireJS as module system.
I have strange problem. I created my test controller and I got problem: controller initialization fires two times.
Firstly, full code available here on GitHub (wait, don't click me, I will explain everything below).
So, problem is in myCtrl.js file. Here is code of this file:
define(['angular'], function (angular) {
var module = angular.module('main.myModule', []);
module.controller('main.myCtrl', function ($scope) {
console.log($scope.$id);
$scope.bob = function () {
}
})
});
It is included in main/controllers/controllers.js by this:
define(['app', 'main/controllers/myCtrl'], function (app) {
var module = angular.module('main.controllers', ['main.myModule']);
});
This file included in main.js by this code:
angular.module('main', ['ngRoute', 'main.services', 'main.controllers', 'main.directives']);
And main.js is included into app.js:
var app = angular.module('myApp', ['ngRoute', 'main', 'common']);
So, I incidentally noticed, that function definition in myCtrl controller fired two times. I put console.log there and saw this:
Can you please explain me why is this happens? Why controller is being initialised two times?
Also, I have this in ng-inspector:
So one scope is created as child for another scope. Notice, that scope with id 3 has correct controller name.
If you use ng-route to register controllers and bind them with views, then don't add them again using attributes in your html files.

Retrieving Constants\string values from a separate JS File

I am developing an Angular JS application.
I would like to know what is the best practice to include string values in our code.
I am planning to use another JS File which contains all the constant values. I will call this JS file in each and every JS(Controller) to refer the string values.
You can define constants in angular like
angular.module('moduleName',[]).constant('constName',string|object|array);
You can inject in directive or controller or wherever you want.
angular.module('moduleName',[]).directive('directiveName', ['constName', function(constName){...});
You have several options.
Global value. You can use your constants in form of the javascript object which would be globally accessible across the application. For example, your file could look something like this:
config = {
host: 'domain',
port: '1234'
};
Obvious disadvantage is that those values are not really a constants and can be easily changed, so it's error prone.
Angular config module. More reliable and cleaner option is to create a separate module to be used as a dependency for main app module. You would still have separate file for your constants but instead of some global variable this file would hold angular module with constant service. Something like this:
angular.module('app.config', []).constant('config', {
host: 'domain',
port: '1234'
});
Then in main application you would configure app like
angular.module('app', ['app.config']).config(function(config) {
// console.log(config);
});
Here is the sample code;
var app = angular.module('plunker', []);
app.constant('configs', {host:'localhost',port:8080});
app.controller('MainCtrl', function($scope, configs) {
$scope.name = configs.host;
});
here is demo plunker
Angular has a built in way of providing constants, e.g:
angular.module('foo', ['ngRoute']) // Your angularjs module
// Decide a name for the bucket of constants, then just declare the
// constants in turn as an object literal:
.constant("HTTP_CONSTANTS", {
"URL": "http://localhost",
"PORT": "80"
})
Then you can load it anywhere where you have access too you foo module using dependency injection, i.e.:
angular.module('foo')
.controller('bar', function (HTTP_CONSTANTS) {
... // Use HTTP_CONSTANTS.URL or HTTP_CONSTANTS.PORT, for example
})
Here's a good primer on using constants:
http://twofuckingdevelopers.com/2014/06/angularjs-best-practices-001-constants/
You can use factory for this purpose and inject this factory where ever you want these constants.
var app=angular.module('Myapp', []);
app.factory('ConstantService', function(){
var constant={temp:'c'};
var getConstants=function(){
return constant;
};
return{
constants:getConstants;
}
});
app.controller('MyController',['ConstantService' function (ConstantService){
var constant= ConstantService.constants;
}]);

concatenate javascript in anonymous function with gulp

I use gulp to concat my scripts into one file. Before concatenation I've split up my .js files into seperate files.
So I've got app.js where I declare my angular app and some other stuff. But I've also got route.js where I declare my routing. However, the declaration of my angular app in app.js is wrapped inside an anonymous function, so when it concatenates app.js and route.js, route.js falls outside the scope of the declaration of my Angular app.
Is there some way to inject a script into the scope with Gulp in stead of concatenate it all together? Or is there some other approach I'm missing, apart from didging JSLint and the anonymous function?
If you're not using CommonJS or AMD modules and just concatenating scripts then just make sure each concatenated script gets the module it needs in it's own scope.
(function() {
// Declare app
var app = angular.module('Application', ['ngRoute']);
// Do stuff with variable app in scope.
})();
Now in your routes.js
(function() {
// Grab the already created module for use
// in this scope.
var app = angular.module('Application');
app.config([
'$locationProvider',
'$routeProvider',
function($locationProvider, $routeProvider) {
$locationProvider.html5Mode = true;
$routeProvider.when('/', {
controller : 'MyCtrl',
templateUrl : 'index.html'
});
}
]);
})()

Use underscore inside Angular controllers

How do I use underscore library inside angularjs controllers?
On this post: AngularJS limitTo by last 2 records
somebody suggested to assign an _ variable to the rootScope so that the library will be available to all the scopes within the app.
But I'm not clear where to do it. I mean should it go on the app module declaration? i.e:
var myapp = angular.module('offersApp', [])
.config(['$rootScope', function($rootScope) { }
But then where do I load underscore lib? I just have on my index page the ng-app directive and script reference to both the angular-js and underscore libs?
index.html:
<head>
</head>
<body ng-app="offersApp">
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="scripts/vendor/angular.js"></script>
<script src="scripts/vendor/underscore.js"></script>
...
How do I achieve this?
When you include Underscore, it attaches itself to the window object, and so is available globally.
So you can use it from Angular code as-is.
You can also wrap it up in a service or a factory, if you'd like it to be injected:
var underscore = angular.module('underscore', []);
underscore.factory('_', ['$window', function($window) {
return $window._; // assumes underscore has already been loaded on the page
}]);
And then you can ask for the _ in your app's module:
// Declare it as a dependency of your module
var app = angular.module('app', ['underscore']);
// And then inject it where you need it
app.controller('Ctrl', function($scope, _) {
// do stuff
});
I have implemented #satchmorun's suggestion here:
https://github.com/andresesfm/angular-underscore-module
To use it:
Make sure you have included underscore.js in your project
<script src="bower_components/underscore/underscore.js">
Get it:
bower install angular-underscore-module
Add angular-underscore-module.js to your main file (index.html)
<script src="bower_components/angular-underscore-module/angular-underscore-module.js"></script>
Add the module as a dependency in your App definition
var myapp = angular.module('MyApp', ['underscore'])
To use, add as an injected dependency to your Controller/Service and it is ready to use
angular.module('MyApp').controller('MyCtrl', function ($scope, _) {
...
//Use underscore
_.each(...);
...
I use this:
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._;
});
See https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection about halfway for some more info on run.
You can also take a look at this module for angular
https://github.com/floydsoft/angular-underscore
If you don't mind using lodash try out https://github.com/rockabox/ng-lodash it wraps lodash completely so it is the only dependency and you don't need to load any other script files such as lodash.
Lodash is completely off of the window scope and no "hoping" that it's been loaded prior to your module.
you can use this module -> https://github.com/jiahut/ng.lodash
this is for lodash so does underscore

AngularJS defining angular.module() multiple times

What is the behaviour of calling angular.module('myModule') multiple times?
For example, I wish to define my routes and my directives in separate .js files.
Is this safe?
eg:
//routes.js
angular.module('app',['$strap'])
.config(function($routeProvider, $locationProvider) {
...
});
//directives.js
angular.module('app')
.directive('formInput', function() {
...
Also, what is the impact of defining the dependencies multiple times? Is this additive, or last-in-wins?
eg:
angular.module(name[, requires], configFn);
...
requires(optional) – {Array.=} – If specified then new module is being created. If unspecified then the the module is being retrieved for further configuration.
-- angular.module docs
I would interpret that as follows: you can only define the dependencies once -- the first time you call angular.module for a particular module. You can call angular.module() multiple times after that, but the requires option must not be specified.
You should only create your module once. According to the docs, if you create a module with a name that already exists, it will overwrite the previous one. (So last-in-wins.)
angular.module('app', []);
You can retrieve your module as many times as you like and in separate files if you wish. You will typically retrieve your module multiple times to declare services, controllers, directives, etc.
angular.module('app').service('myService', ...);
angular.module('app').controller('myController', ...);
angular.module('app').directive('myDirective', ...);
In the AngularJS docs on Modules, see the section called Creation versus Retrieval.
I'm new to angular, but this is my understanding: you create one module in each file with a namespaced module name, and in your main module you require those modules.
// in main app.js file
var app = angular.module('myapp',
['myapp.routers', 'myapp.directives', 'myapp.filters']);
// in filters.js
angular.module('myapp.filters', []).filter(....)
// in routers.js
angular.module('myapp.routers', []).router(....)
// in directives.js
angular.module('myapp.directives', []).directive(....)

Categories