Sharing Modules in AngularJs - javascript

We currently have a setup for our angularjs apps, where there's a file called "app.js" which holds
var app = angular.module('VolumeOutputOptions', [
'someDirectiveModule',
'someServiceModule'
]);
Apart from code shared between apps like someDirectiveModule, almost every class depends on this global variable. This has occasionally led to issues where a new dependency is added, but it turns out that "app" is used in contexts where that dependency hasn't been included. Also, global variables, bleugh.
Is there a better way to share a single module between all the directives and controllers of your app? For example, would
angular.module('VolumeOutputOptions').directive(...);
angular.module('VolumeOutputOptions').controller(...);
be two separate modules with the same name, or would angular detect and merge them?

If you use like
angular.module('VolumeOutputOptions').directive(...);
angular.module('VolumeOutputOptions').controller(...);
to use like this there must be a something like angular.module('VolumeOutputOptions', []) to create the module before it use.
then both of them are assign to same module VolumeOutputOptions.
if you define a module like angular.module('moduleName', []) with the second array parameter for dependency then only angular create a new module. If there is no array parameter passed then angular will refer to the previous module which declared with same name.

Related

One inject from multiple constants - Angular

I am using Angular constant as an configuration file for my services, my problem is that this file can become huge and i am would like to separate the configuration into multiple files. But i donĀ“t want to create a new Angular constant that i need to inject in the services that uses constants.
Is there a way to have only one main constant file that requires all the other files so that there is only one inject into the services? Or is it possibly to create one constant from all js files in a specific folder?
Other solutions to this problem would also be very helpful.
You can use $provide.decorator for that:
$provide.decorator('yourSettings', ['$delegate', function ($delegate) {
$delegate.newProp = 'new value';
return delegate;
}]);
See docs.

Custom directives on AngularJS pages without specific ng-app module set

I have some simple pages that don't need a specific application module to be provided in the ng-app attribute. But those pages also use some of my custom directives.
As it seems natural I've put all my directives in separate namespace (namely module) i.e. MyApp.Directives.
This is all great when I also provide my application module, because I add MyApp.Directives as dependency and it works.
angular.module("MyApp", ["MyApp.Directives", ...])
But. As said I also have some very simple pages, that don't really require any particular application module because they don't need any custom controllers or anything. They're just driven by ng-... attributes/directives.
Question
I know I can simply add all my custom directives to ng module and they will become accessible to all pages. Those with custom application module and those without. But this beats the purpose of modules, so I'm wondering if there's any other way to tell dependency injector of my additional directives/filters?
I would like to avoid any unneeded code in my application to keep is small and maintainable. (what AngularJS is all about). What I'm looking is actually some sort of hack that I'd be using in my directives' files to make ng module aware of my directives but without adding them to ng module directly... A rather advanced Angular question as it likely involves some internals manipulation.
I've tried manully adding my directives' module to angular.module("ng").requires array but that didn't do the trick.
#1) If you only have one module you can do it with ngApp:
<html ng-app="MyApp.Directives">
#2) If you have multiple modules you can use angular.bootstrap like so:
angular.element(document).ready(function(){
angular.bootstrap(document,['MyApp.Directives','MyApp.Filters']);
});
#3) Or just create a simple module for declaring dependencies:
<html ng-app="myApp">
......
<script>
angular.module('myApp',['MyApp.Directives','MyApp.Filters']);
</script>
If we could only write something like this:
<html ng-app="MyApp.Directives MyApp.Filters">
I made a patch to the source code:
function angularInit(element, bootstrap) {
// some code
if (appElement) {
bootstrap(appElement, module ? module.split(/\s+/) : []); // split by spaces :)
}
}
Here is a demo: http://plnkr.co/edit/kSrY3WYzLG39NJ4UgTRM?p=preview

Javascript global declaration

I've just started out with javascript and came across this line in a file called global.js There is only one line in the file. I'm not sure what does App do. Any ideas?
Filename: globals.js
//The Application
App = {};
it creates an object with a name of App... that's all it does.
I would assume that the idea behind the global.js file in your case is to include the file in your base html/template so that the variables in there can be accessed from anywhere in the app.
In some of our projects, we've had global files like this containing references to collections and "setting" variables, which is quite handy :)
It is creating an object named App in the global namespace. App has no functions or attributes (yet).
It (implicitly) declares a variable called App in a "global" context and assigns an empty object as its value. Assuming this is used on a web page somewhere, it's the same as declaring window.App = {}.
How this affects the rest of your application, we won't know until you post more relevant code.
This script just instantiate this empty Object. Probably, others scripts that ran along with this uses that object and depends that it is created there.

Creating a "controller" script for Node.js

I'm creating a program in Node.js. I'm pretty new to programming anything other than small javascript functions for websites so please bear with me if my terminology/ideas are totally wrong.
I originally had the entire program in one giant (~500 line) script file. Several people suggested I split it up into separate classes, where each class only has one 'job' to complete. I like this idea as it has helped me really streamline my code and make it more modular and manageable.
My issue is: How do I access these classes from a central file?
For instance, pretend I have 3 classes, in 3 separate javascript files, all containing 3 functions each. I want to access and pass data to/from all of these from one central "controller" script. What's the best way to do this? Can I just require it into a variable, then access the script's functions like so?
var class1 = require('./class1.js');
class1.function1(); // call the first function contained in class1.js
Is such a thing even possible? Again, totally new to this.
NodeJS supports CommonJS modules. A CommonJS module provides three global variables: module, exports and require.
You can export your API by adding to the exports object and require these files just like other node modules (add ./ to indicate that it is relative to the current file), assign it to a variable and access the values you added to that files exports object:
// first-module.js
exports.hello = 'world';
exports.num = 23;
// main.js
var first = require('./first-module');
console.log(first.hello);
console.log(first.num);
You need to add functions to the exports object in class1.js.
require("./class1") will return this object.

How to correctly modularize a node.js project?

I'm creating a node.js project following the class constructor pattern:
function my_class(x,y){
this.x = x;
this.y = y;
}
The starting point of the project is the main.js file. Any class of the project must be able to access global objects (such as "world" and "socket") which are defined on main.js. I found 4 options:
I define my classes inside main.js. They'll have access to main.js's globals for being on it's closure, but main.js will become bloated.
I move the class to another file such as my_class.js and require() it. This doesn't work because my_class's instances will lose the closure context and no longer be able to access main.js's globals.
I move the class to another file and manually inject dependencies to it's constructor (ex: my_class(world,socket)). The problem is, code becomes much more complicated and weird semantics such as "my_instance.world" pop on the source, which is nonsense because "world" is not property of my_class.
I move the class to another file and require it using my_class = eval(fs.readFileSync(()) instead of require. This works just fine as my_class gets main.js's closure context, and is the solution I'm using, but seems hacky.
Which is the right way to modularize such node.js project?
If I understood you correctly the possible solution:
main.js:
(function(){
var global = "test"; // this you wanna have as a closure
var my_class = require('./my_class')(global);
my_class.go();
})();
my_class.js:
module.exports = function(global){
return {
go: function(){
console.log(global);
}
};
};
So it's similar to your 3. option
Your problem seems tricky because you have a circular dependency: main.js depends on the functionality of my_class and my_class depends on the data of main.js.
By putting the data of main.js into the global object you resolve the circular dependency:
main.js depends on the functionality of my_class.js
main.js depends on the data in the global object
my_class.js depends on the data in the global object
Now, to get rid of putting the data into the global object, implement a third module in let us say data.js. Then you require the sources like this:
main.js requires data.js
main.js requires my_class.js
my_class.js requires data.js
Since modules in node.js are singletons both main.js and my_class.js will get the same instance of data.js.
If you want to make variables in main.js available anywhere, then you can assign properties to the global object. See node.js global variables? for example. It would work fine as long as you don't over do it. With Neo's solution, you gain a little more flexibility for example with testing, because you can "inject" an arbitrary object into the module. Not every module has to use the same "global" per se.

Categories

Resources