Angularjs - separating directive files, but staying on the same module - angularjs

I'm trying to separate a directive to another file, without having to declare a new module - not doing:
angular.module('myapp.newmodule',[]).directive
but just :
angular.module('myapp.directives').directive(''
the myapp.directives module exists in another file and works fine. but when I try to use it in another file as shown above (without []) it fails.
following this answer It believe my approach should work, but for some reason it fails..

When you first declare a module it needs to have the dependency argument. Afterwards you can reference that same module using only the module name argument.
/* create module */
angular.module('myapp.newmodule',['ngRoute','ngResource']);
/* declare components of same module, note same name*/
angular.module('myapp.newmodule').directive....
If you want to create new modules, you need to inject them in the main ng-app module as dependencies.
/* main ng-app module , injects another module you created below*/
angular.module('myapp.newmodule',['ngRoute','ngResource','myUploader']);
/* new module, must have dependency argument */
angular.module('myUploader',[]).directive...

Wherever it is just refer to the module name (even in different files) and attach the directives.
Javascript will just see what is attached to the module and not see which file it came from.
file1.js
angular.module('module-name')
.directive('directive1', function () {
return {
....
};
});
file2.js
angular.module('module-name')
.directive('directive2', function () {
return {
....
};
});
Only thing is don't forget to include both the js files in the view html file.
say
index.html
<script src="file1.js"></script>
<script src="file2.js"></script>

You don't need to chain them together, the link you posted has the answer at the bottom of the question.
In the first file you need to create your app module:
var myApp = angular.module('myApp ', []);
Then in each file you can attach additional things to myApp:
myApp.directive('ngValidate', ['$parse', function ($parse) {
....
}]);
Personally I never chain this stuff together, rather, I put it in separate files.

Related

AngularJs Inject multiple directives from separate files into one common module

there is a question regarding referencing and injecting directives into different modules. The goal is to inject multiple directives located in separate files into one module, and then inject that common module to other places. I have multiple directives, defined in separate files, for example:
define(['angular'], function (angular) {
angular.module('ngCustomDirective')
.directive('ngCustomDirective', function () {
...
});
});
in separate file, I have:
define(['angular'], function (angular) {
angular.module('ngCustomDirective2')
.directive('ngCustomDirective2', function () {
...
});
});
after that the directive is referenced in another module (different file):
define(['angular','ngCustomDirective', 'ngCustomDirective2'], function (angular, ngCustomDirective, ngCustomDirective2) {
angular.module('directives', [ngCustomDirective, ngCustomDirective2]);
return 'directives';
});
next, this 'directives' module is injected into another module. The code above doesn't work. What I'm doing wrong here?
Can you try injecting the module within the single quote as below?
angular.module('directives', ['ngCustomDirective',
'ngCustomDirective2']);
follow along on this answer's guideline thats exactly what you need to do..
open link

Can I divide up my app.js file into multiple files in Angular JS?

In my app.js file I have my Angular code like this:
var app = angular
.module('app',
['...'])
.config([
'...',
function (
...) {
}])
.factory('requestInterceptor', function ($q, $rootScope) {
..
return {
..
};
})
Is it possible for me to move the code for the config and the factory out of the file and if so then how do I link this up to the app variable?
I have an app setup this way.
What you can do is declare the module in one file before and separate from everything else. Then just make sure it's the first script file referenced in your HTML.
After that you should be able to just add factories, configs and what not to the app in other files.
Yes. If you define a module, app:
angular.module('app',[]); // Including the [], or list of module dependencies
then you can refer to it later, in other files, by calling module without the second parameter:
angular.module('app').factory('requestInterceptor',...
It is confusing: module is used for both creating a new module, and to add to an existing one, depending on whether you have passed an array as its second parameter.

How to automatically load a module in AngularJS without specifying it as a dependancy

ngMock does some magic to automatically include itself if you include angular-mocks.js in your index.html.
What's the simplest way to force angular to load a module in test mode simply by including a file and not having to edit any module dependencies.
The only way to load a module is by calling angular.module(...). ngMocks loads "itself" by calling:
angular.module('ngMock', ['ng']).provider(...).config(...);
You don't need to declare a module as a dependency to load it. You can just include angular.module('<moduleName>', [<moduleDependencies>...]); in its script.
If you mean "how is ngMock automagically added to the dependency list of any module loaded using window.module or angular.mock.module, it is because ngMocks creates a custom injector, such that it takes the list of dependencies and prepends 'ngMock':
window.inject = angular.mock.inject = function() {
...
return isSpecRunning() ? workFn() : workFn;
...
function workFn() {
var modules = currentSpec.$modules || [];
modules.unshift('ngMock'); // <-- this line does the trick
modules.unshift('ng');
...
You could create your own function that prepends your module in the list of dependencies before instantiating, but I hardly believe this will help in testing. On the contrary, it will be one more source of errors (and will result in possibly "hiding" dependency errors).

AngularJS best practices for module declaration?

I have a bunch of Angular modules declared in my app. I originally started declaring them using the "chained" syntax like this:
angular.module('mymodule', [])
.controller('myctrl', ['dep1', function(dep1){ ... }])
.service('myservice', ['dep2', function(dep2){ ... }])
... // more here
But I decided that wasn't very easy to read, so I started declaring them using a module variable like this:
var mod = angular.module('mymodule', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
The second syntax seems a lot more readable to me, but my only complaint is that this syntax leaves the mod variable out in the global scope. If I ever have some other variable named mod, it would be overridden with this next one (and other issues associated with global variables).
So my question is, is this the best way? Or would it be better to do something like this?:
(function(){
var mod = angular.module('mymod', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
})();
Or does it even matter enough to care? Just curious to know what the "best practices" are for module declaration.
'Best' way to declare a module
As angular is on the global scope itself and modules are saved to its variable you can access modules via angular.module('mymod'):
// one file
// NOTE: the immediately invoked function expression
// is used to exemplify different files and is not required
(function(){
// declaring the module in one file / anonymous function
// (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
// which are very hard to dedect)
angular.module('mymod', []);
})();
// another file and/or another anonymous function
(function(){
// using the function form of use-strict...
"use strict";
// accessing the module in another.
// this can be done by calling angular.module without the []-brackets
angular.module('mymod')
.controller('myctrl', ['dep1', function(dep1){
//..
}])
// appending another service/controller/filter etc to the same module-call inside the same file
.service('myservice', ['dep2', function(dep2){
//...
}]);
// you can of course use angular.module('mymod') here as well
angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
//..
}])
})();
No other global variables are required.
Of course it depends all on preferences, but I think this is kind of the best practise, as
you don't have to pollute the global scope
you can access your modules everywhere and sort them and their functions into different files at will
you can use the function-form of "use strict";
the loading order of files does not matter as much
Options for sorting your modules and files
This way of declaring and accessing modules makes you very flexible. You can sort modules via function-type (like described in another answer) or via route, e.g.:
/******** sorting by route **********/
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...
How you sort it in the end is a matter of personal taste and the scale and type of the project. I personally like to group all files of a module inside of the same folder (ordered into sub-folders of directives, controllers, services and filters), including all different test-files, as it makes your modules more reusable. Thus in middle-sized projects I end up with a base-module, which includes all basic routes and their controllers, services, directives and more or less complex sub-modules, when I think they could be useful for other projects as well,e.g.:
/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...
angular.module('app', [
'app.directives',
'app.filters',
'app.controllers',
'app.services',
'myMapSubModule'
]);
angular.module('myMapSubModule',[
'myMapSubModule.controllers',
'myMapSubModule.services',
// only if they are specific to the module
'myMapSubModule.directives',
'myMapSubModule.filters'
]);
For very big projects, I sometimes end up grouping modules by routes, as described above or by some selected main routes or a even a combination of routes and some selected components, but it really depends.
EDIT:
Just because it is related and I ran into that very recently again: Take good care that you create a module only once (by adding a second parameter to the angular.module-function). This will mess up your application and can be very hard to detect.
2015 EDIT on sorting modules:
One and a half year of angular-experience later, I can add that the benefits from using differently named modules within your app are somewhat limited as AMD still does not really work well with Angular and services, directives and filters are globally available inside the angular context anyway (as exemplified here). There is still a semantic and structural benefit though and it might be helpful being able to include/ exclude a module with a single line of code commented in or out.
It also almost never makes much sense to separate sub-modules by type (eg. 'myMapSubModule.controllers') as they usually depend on each other.
I love the angular-styleguide by Johnpapa, and here are some rules that related to this question:
Rule: Named vs Anonymous Functions
Avoid using anonymous functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', function() { })
Instead, use named functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', Dashboard);
function Dashboard() { }
As the author says: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.
Rule : Define 1 component per file.
Avoid multiple components in one file:
angular
.module('app', ['ngRoute'])
.controller('SomeController', SomeController)
.factory('someFactory', someFactory);
function SomeController() { }
function someFactory() { }
Intead, use one file to define the module:
// app.module.js
angular
.module('app', ['ngRoute']);
one file just uses the module to define a component
// someController.js
angular
.module('app')
.controller('SomeController', SomeController);
function SomeController() { }
and another file to define another component
// someFactory.js
angular
.module('app')
.factory('someFactory', someFactory);
function someFactory() { }
Of course, there are many other rules for modules, controllers and services that are quite useful and worth reading.
And thanks to comment of ya_dimon, the above code should be wrapped in IIFE, for example:
(function (window, angular) {
angular.module('app')
.controller('Dashboard', function () { });
})(window, window.angular);
I recently had this conundrum as well. I had started off just like you using the chained syntax, but in the long run it becomes unwieldy with large projects. Normally I'd create a controllers module, a services module and so on in separate files and inject them into my main application module found in another file. For Example:
// My Controllers File
angular.module('my-controllers',[])
.controller('oneCtrl',[...])
.controller('twoCtrl',[...]);
// My Services File
angular.module('my-services',[])
.factory('oneSrc',[...])
.facotry('twoSrc',[...]);
// My Directives File
angular.module('my-directives',[])
.directive('oneDrct',[...])
.directive('twoDrct',[...]);
// My Main Application File
angular.module('my-app',['my-controllers','my-services','my-directives',...]);
But each one of these files was getting way to large as the project grew. So I decided to break them up into separate files based on each controller or service. I found that using angular.module('mod-name'). without the injection array, is what you need for this to work. Declaring a global variable in one file and expecting that to be readily available in another just doesn't work or could have unexpected results.
So in short my application looked something like this:
// Main Controller File
angular.module('my-controllers',[]);
// Controller One File
angular.module('my-controllers').controller('oneCtrl',[...]);
//Controller Two File
angular.module('my-controllers').controller('twoCtrl',[...]);
I did this to the services file as well, no need to change the main application module file you'd still be injecting the same modules into that.
One other practice is to stuff controllers, directives, etc in their own modules and inject those modules into your "main" one:
angular.module('app.controllers', [])
.controller('controller1', ['$scope', function (scope) {
scope.name = "USER!";
}]);
angular.module('app.directives', [])
.directive('myDirective', [function () {
return {
restrict: 'A',
template: '<div>my directive!</div>'
}
}]);
angular.module('app', [
'app.controllers',
'app.directives'
]);
Nothing is left in the global scope.
http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview
I like to divide my files and my modules.
Something like this:
app.js
var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']);
myApp.config(['$routeProvider', function($routeProvider) {
/* routes configs */
$routeProvider.when(/*...*/);
}]);
directives.js
var myDirectives = angular.module('myApp.directives', []);
myDirectives.directive( /* ... */ );
service.js
var myServices = angular.module('myApp.services', []);
myServices.factory( /* ... */ );
Im not a big fan of the "chained style", so I prefer to write down my variable always.
I suggest to follow Angularjs Style Guide.
They handle all concept from naming convention, to modularize your app and so on.
For angular 2, you can check Angular 2 Style Guide
For me, chaining is the most compact way:
angular.module("mod1",["mod1.submod1"])
.value("myValues", {
...
})
.factory("myFactory", function(myValues){
...
})
.controller("MainCtrl", function($scope){
// when using "Ctrl as" syntax
var MC = this;
MC.data = ...;
})
;
That way I can easily move components between modules, never need to declare the same module twice, never need any global variables.
And if the file gets too long, solution is simple - split into two files, each declaring its own module at the top. For more transparency, I try to keep one unique module per file and name it resembling the full path of the file. This way also I never need to write a module without [], which is a common pain point.

How do I write a custom module for AngularJS?

I need to write a custom module for AngularJS, but I can't find any good documentation on the subject. How do I write a custom module for AngularJS that I can share with others?
In these situations were you think that the docs can't help you any more, a very good way to learn is to look at other already-build modules and see how others did it, how they designed the architecture and how they integrated them in their app.
After looking at what others did, you should have at least a starting point.
For example, take a look at any angular ui module and you will see many custom modules.
Some define just a single directive, while others define more stuff.
Like #nXqd said, the basic way to create a module is:
// 1. define the module and the other module dependencies (if any)
angular.module('myModuleName', ['dependency1', 'dependency2'])
// 2. set a constant
.constant('MODULE_VERSION', '0.0.3')
// 3. maybe set some defaults
.value('defaults', {
foo: 'bar'
})
// 4. define a module component
.factory('factoryName', function() {/* stuff here */})
// 5. define another module component
.directive('directiveName', function() {/* stuff here */})
;// and so on
After defining your module, it's very easy to add components to it (without having to store your module in a variable) :
// add a new component to your module
angular.module('myModuleName').controller('controllerName', function() {
/* more stuff here */
});
And the integration part is fairly simple: just add it as a dependency on your app module (here's how angular ui does it).
angular.module('myApp', ['myModuleName']);
If you want to look for a good example, you should look into the current module written in angularJS. Learn to read their source code. Btw this is a structure that I use to write modules in angularJS:
var firstModule = angular.module('firstModule', [])
firstModule.directive();
firstModule.controller();
// in your app.js, include the module
This is the basic one.
var newMod = angular.module('newMod', []);
newMod.controller('newCon', ['$scope', function ($scope) {
alert("I am in newCon");
$scope.gr = "Hello";
}]);
Here newMod is a module which has no dependencies [] and has a controller which has an alert telling you are in the controller and a variable with value hello.

Resources