1

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:

  1. Option A: http://jsfiddle.net/nxhn31yv/ (both assets and toolbar have service)
  2. Option B: http://jsfiddle.net/oszop5j4/ (assets has service, parent of toolbar has service and toolbar updates it)
  3. Option C: http://jsfiddle.net/a7nf31d3/ (Parent of all of them has service, passes it down)

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?

1
  • 1
    I don't know if your actual use cases are different, but to share information between the controller and the directives, I'd use the scope instead! A showMarkers boolean in the root scope would be way better than a service here. Commented Feb 19, 2015 at 8:25

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1
+50

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.