I am new in AngularJS DI, and I am wondering how to do things that I usually do in Ninject. I understand the limitations, so if it is not possible, a workaround will do.
I have to create objects that handle different event types, I usually follow the strategy pattern, and with Ninject in C# I can use multi-injection to inject an array of strategies in the constructor of my strategy broker.
The idea is that I would like to create more "handlers" (strategies) and add them to the AngularJS DI system, without alter common code. I have done this in JS before, by having an object where I can append the new strategies, but I wonder which is the right way of doing it in Angular.
Would be possible somehow in Angular to do something similar?
Related
In many cases in C# i can use interface to get loose coupling between components.
for example a component could retrieve an
ITextFileReader reader = dic.Resolve<ITextFileReader();
No matter which implementation is currently bound. For example in test environment i could pass a spy or mock.
In node.js i use
require('./myTextReader.js")
but there is a fix dependency to that specific file.
what is the best practice to get the described behavior f orm above in node.js implemented?
What I don't want to do is to have some facade / wraper with "If...." clauses which may decide who to delegeate the call
Also i want to avoid to have the setup configuration as a part of my production code. the setup code should be outside the domain logic in the Application Composition layer.
So as best thing i would have something like a component registration, and consumer which just use the registration information to get there instance (without knowing anything ábout the registration details )
i found di.js which seems to be the angular.js approach. I could also implement some kind of di by myself. But reinventing the wheel is often a bad decission.
What is the current best practice / state of the art to do this?
For a project I am working on, one of the things I've written is an instantiable service for an Angular UI Bootstrap Calendar control.
You can see the plunker for it in action here.
The code question I have is more of an architectural and best-practices question. Specifically, I think I've written an Angular anti-pattern.
Services - like the calendarSvc - are singletons, yet I am explicitly circumventing this by making the factory return a constructor function.
That being said, there is a concrete business need for 1-n calendars to exist on a single page. This code is an effective refactor of the code needed to manage a single calendar, so it definitely helps the code to be more DRY.
Question: What are some effective alternatives to this instantiable service that still let me specify instances of reusable Calendar objects as needed, but are done without circumventing the Angular way of managing the code?
What you did is not a antipattern, but indeed best practice!
See this style guide page for example: http://github.com/mgechev/angularjs-style-guide#services.
You did not circumvent the Angular way. The idea of the factory is the possibility to return constructor functions. The other alternative to creating services is the service-method of module which would automatically instantiate your service with the new keyword.
Take also a look at this other StackOverflow answer as reference: https://stackoverflow.com/a/20110304/669561
I am working on a web app with AngularJS which I just started learning a while back. I find it extremely useful but after working on it for few days, I figured that the app is going to get all messed up sooner or later, since I wrote all my 'backend' code in one controller.
The app uses lots of $http requests to get/post/delete/put data from/to remote servers and also many scope variables which are needed to manipulate page in one way or another.
I checked lots of tutorials/info sites on AngularJS (similar question, great blog post for instance) but I am still not sure how to implement one of my own within my app. I was wondering what is the usual case with using your own service/module/directive/factory? I am hoping to restructure my code a little bit so everything is going to seem more organized; at the moment I think I am not fully taking advantage of AngularJS with all my code in one place and without using any services/modules besides my main app module and controller and built-in $http.
So you can better understand my problem, so far I only use two javascript files, first one being app.js :
var app = angular.module('MyAppName',[]);
and the second one being controller.js (I could of course use only 1 file for this):
app.controller("MyController", function($scope, $http){
// all my functions/variables in here
// I initialize them with $scope.someName = … if they are needed within this controller view.
// If they are not needed within view I initialize them (functions for instance)
// as functionName = function(){};
}
Everything works as it should this way, but I think this approach is not using all the capabilities of AngularJS. For instance: I don's use routing which I probably should?(url stays the same all the time). I also don't use any other advanced features of angularJS such as custom services/directives/modules.
So I ask: how can I restructure my code so that it uses more of AngularJS features and so that it stays readable? When do you usually create your own service/module/factory ?
I kind of didn't grasp the whole thing on AngularJS site, probably because I started developing too early with not enough knowledge and now I hardly get it (was too much into two-way-binding and started coding immediately).
Any help on the subject is appreciated.
EDIT:
OK, I see I should clear some things up: my main problem is not the outside folder/file structure, but the code structure itself. Now I have one controller which contains every variable (30+) and function to use in my web app, such as login function, sign out function, functions for showing/hiding parts of page, function to add/delete data to/from server etc…
I would like to be able to structure these functions/variables as some independent parts somehow, but I am not sure how.
EDIT2:
I figured how to use services for instance, but unfortunately you cannot call service functions inside views, such as with ng-click directly... you can only call $scope variables which is logical actually... unfortunately i still don't know how to organize my code to seem more readable and structured
There are lots of opinions about how to organize AngularJS code. Have a look at these blog posts:
Code Organization in Large AngularJS and JavaScript Applications
Code Organization in Angular
There are also lots of sample projects out there that showcase various code organization schemes.
Take a look at the angular-seed project:
https://github.com/angular/angular-seed
One alternative to the above is angular-enterprise-seed:
https://github.com/robertjchristian/angular-enterprise-seed
You didn't mention what backend you're using, but there are also similar "seed" projects demonstrating the recommended code organization scheme for AngularJS + [your backend]. For instance, if you're using Express.js, you might want to take a look at angular-express-seed:
https://github.com/btford/angular-express-seed
Data Binding - Angular JS provides two way binding is automatic synchronization of the data between model and view.
Extensible - AngularJS is customized and extensible . Allows you to create customizable components.
Code Reusability and Maintainability - AngularJS forces you to write code in modular way. Variables and functions can only be created to the respective component(Controller). Provides service and factory implemetation to use across the controllers.
Compatibility - AngularJS is compatible to all major browsers
Testing - AngularJS is designed to be testable so that you can test your AngularJS app components as easy as possible. It has dependency injection at its core, which makes it easy to test.
http://astutejs.blogspot.in/2015/06/advantages-of-angular-js.html
I have an app I am designing using node/mongo/angular, what I am not getting is how is the best way to get my data from mongo into my pages? I can use node, and thru my routes send back data from mongo with my template(hogan in this case), and bind using mustachejs. That works fine for most things. I have one screen that has a decent amount of drop down lists, to bind them for an edit scenario now seems a challenge. I would like to get them bound to an angular model and go about it that way. Is it better to get the data thru the route in node, then use something like ng-init and get it into angular? Or would I be better off not getting the data thru the route in node, and then using angular to perform a "get" request and bind that way?
From the documentation of ng-init, more precisely from the red warning alert at the top of the page...:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
So no, do not use ng-init. While that can be a good strategy for lazy migrations from regular applications to single page applications, it's a bad idea from an architectural point of view.
Most importantly, you lose two things:
An API. The benefit of SPAs is that you have an API and that you're constantly developing and maintaining it, even before it has external users
A clean separation of concerns. Views are strictly limited to presentation, can be cached by the client and all data is transferred through JSON API endpoints.
I would say that the best way to get data from Mongo into your page, is as mnemosyn said, using an API.
Basicly, you can have your API route, f.ex '/api/data' configured and then it can be used by a angular service, (which can use ngResource to make things easier). Any controller that wishes to access this data can use the angular service to get it, do some stuff with it, and then update it using the same angular service.
I'm working within a Javascript + BackboneJS (an MVC framework) + RequireJS framework, but this question is somewhat OO generic.
Let me start by explaining that in Backbone, your Views are a mix of traditional Views and Controllers, and your HTML Templates are the traditional MVC Views
Been racking my head about this for a while and I'm not sure what the right/pragmatic approach should be.
I have a User object that contains user preferences (like unit system, language selection, anything else) that a lot of code depends on.
Some of my Views do most of the work without the use of templates (by using 3rd party libs, like Mapping and Graphing libs), and as such they have a dependency on the User object to take care of unit conversion, for example. I'm currently using RequireJS to manage that dependency without breaking encapsulation too much.
Some of my Views do very little work themselves, and only pass on Model data to my templating engine / templates, which do the work and DO have a dependency on the User object, again, for things like units conversion. The only way to pass this dependency into the template is by injecting it into the Model, and passing the model into the template engine.
My question is, how to best handle such a widely needed dependency?
- Create an App-wide reference/global object that is accessible everywhere? (YUK)
- Use RequireJS managed dependencies, even though it's generally only recommended to use managed dependency loading for class/object definitions rather than concrete objects.
- Or, only ever use dependency injection, and manually pass that dependency into everything that needs it?
From a purely technical point of view, I would argue that commutable globals (globals that may change), especially in javascript, are dangerous and wrong. Especially since javascript is full of parts of code that get executed asynchronously. Consider the following code:
window.loggedinuser = Users.get("Paul");
addSomeStuffToLoggedinUser();
window.loggedinuser = Users.get("Sam");
doSomeOtherStuffToLoggedinUser();
Now if addSomeStuffToLoggedinUser() executes asynchronously somewhere (e.g. it does an ajax call, and then another ajax call when the first one finishes), it may very well be adding stuff to the new loggedinuser ("Sam"), by the time it gets to the second ajax call. Clearly not what you want.
Having said that, I'm even less of a supporter of having some user object that we hand around all the time from function to function, ad infinitum.
Personally, having to choose between these two evils, I would choose a global scope for things that "very rarely change" --- unless perhaps I was building a nuclear powerstation or something. So, I tend to make the logged in user available globally in my app, taking the risk that if somehow for some reason some call runs very late, and I have a situation where one user logs out and directly the other one logs in, something strange may happen. (then again, if a meteor crashes into the datacenter that hosts my app, something strange may happen as well... I'm not protecting against that either). Actually a possible solution would be to reload the whole app as soon as someone logs out.
So, I guess it all depends on your app. One thing that makes it better (and makes you feel like you're still getting some OO karma points) is to hide your data in some namespaced singleton:
var myuser = MyApp.domain.LoggedinDomain.getLoggedinUser();
doSomethingCoolWith(myuser);
in stead of
doSomethingCoolWith(window.loggedinuser);
although it's pretty much the same thing in the end...
I think you already answered your own question, you just want someone else to say it for you : ) Use DI, but you aren't really "manually" passing that dependency into everything since you need to reference it to use it anyways.
Considering the TDD approach, how would you test this? DI is best for a new project, but JS gives you flexible options to deal with concrete global dependencies when testing, ie: context construction. Going way back, Yahoo laid out a module pattern where all modules were loosely coupled and not dependent on each other, but that it was ok to have global context. That global context can make your app construction more pragmatic for things that are constantly reused. Its just that you need to apply that judiciously/sparingly and there need be very strong cases for those things being dynamic.