Reputation: 28750
We're trying to lock down the best method for using services and have come up with three possibilities. This is a much smaller example of a much bigger problem but I hope it gets the point accross. The service in these examples is very simple:
.service("markerService", function(){
var self = this;
self.showMarkers = false;
self.toggleMarkers = function(value){
self.showMarkers = angular.isDefined(value) ? !!value : !self.showMarkers;
};
})
And the dom after it's compiled is also very simple:
<div ng-controller="ParentCtrl" class="ng-scope">
<div class="assetsDirective">
<div>
<div class="assetDirective">Hidden Name: 1</div>
<div class="assetDirective">Hidden Name: 2</div>
</div>
</div>
<div class="toolBarDirective">
<div>
<button>Toggle Markers</button>
</div>
</div>
</div>
The options we've come up with are:
The first one injects the server into two sibling controllers and one of them calls a toggle function to update the value stored within that service.
The second option has it injected into two services that have a parent/child relationship. The parent passes the value to one child which can update it (like an ngmodel) while the child controller with the injected service passes it's value onto it's children which use it.
The third option has the parent pass the value all the way through to both siblings, which in turn has the one sibling pass it to it's children as well.
Which of these fall in line with angulars methodology of how to implement services?
Upvotes: 1
Views: 236
Reputation: 1624
According to Pro Javascript Development by Den Odell, applying a set of methods and properties from one Object directly to another or a prototype of a Class can be a "hack", especially for that developers approaching Angular from Object Oriented Background. Neverthless, when it is being used carefully, can simplify development and code mainteance. That is a mixin design pattern, which avoids extensing subclassing and inheritance chains.
Injecting service into encapsulated directives, will help you avoid parent controllers and inheritance. That is why i choose option A, but use it carefully.
More about mixin.
Another article
Upvotes: 1
Reputation: 7264
Option A is the clear winner for me. It more closely matches the idea of discrete, decoupled web components - the direction in which Angular and web development generally seems to be heading.
For Angular 1.x this means using directives to encapsulate all markup/logic that is bound together. Typically ng-controller
in your markup should NOT be required. It should be possible to identify the dependencies (injected or related directives) for any directive by looking ONLY at the declaration of that directive.
Option B and C violate these simple principles and therefore (assuming actual implementations are more complex than these simple examples) are likely to be much more painful in terms of maintenance and debugging.
Upvotes: 5
Reputation: 1218
I would say option A is the best way to do it.
I believe one of the greatest things Angular teaches you is how to modularize your code. Programming in such a way where if you wanted to, you could remove, add any piece anywhere. So with that, you would try to avoid using anything that is dependent upon another piece. Your Option A succeeds in this way.
Of course sometimes it is unavoidable, but I use that as a general rule. It makes things easier to understand and follow, keeps things clean.
edit: It also protects yourself from changes to scope in the future.
Upvotes: 2