There's quite a bit out there about using controllers and services 
together, and was hoping to start a discussion to try and nail down some 
best practices.

There's three different methods i've seen for using controllers and 
services together. They all assume (I believe) that you're holding the 
state in your services, and your controllers are stateless. 

Method 1: Expose Service to Template

This one is probably the simplest. You treat your service like a model and 
you put it on scope (or on your controller and your controller on scope 
using the "as" syntax) and then in your templates access its properties and 
methods.

app.service('serviceCounter', function() {
  this.count = 0;
  this.increment = function () {
    this.count++;
  };
})
.controller('ServiceCounterController', function (serviceCounter) {
  this.serviceCounter = serviceCounter
});
 
<div ng-controller="ServiceCounterController as serviceCounterCtrl">
  {{serviceCounterCtrl.serviceCounter.count}}
  <button ng-click="serviceCounterCtrl.serviceCounter.increment()">Add One
</button>
</div>

Method 2: Wrap Methods in Controller

For this, you create a specific API in your controller that uses methods 
from your service:

app.service('serviceCounter', function() {
  this.count = 0;
  this.increment = function () {
    this.count++;
  };
})
.controller('ServiceCounterController', function (serviceCounter) {
  this.getCount = function () {
    return serviceCounter.count;
  };
  this.addOne = function () {
    serviceCounter.increment();
  };
});

<div ng-controller="ServiceCounterController as serviceCounterCtrl">
  {{serviceCounterCtrl.getCount()}}
  <button ng-click="serviceCounterCtrl.addOne()">Add One</button>
</div>

Method 3: Reassign Service Methods to Controller

Here, you would reassign your methods onto the controller:

app.service('serviceCounter', function() {
  var count = 0;
  this.increment = function () {
    count++;
  };
  this.getCount = function () {
    return count;
  };
})
.controller('ServiceCounterController', function (serviceCounter) {
  this.getCount = serviceCounter.getCount;
  this.addOne = serviceCounter.increment;
});

<div ng-controller="ServiceCounterController as serviceCounterCtrl">
  {{serviceCounterCtrl.getCount()}}
  <button ng-click="serviceCounterCtrl.addOne()">Add One</button>
</div>

Obviously if someone has better examples of any of these please share. 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

My pros and cons list is as follows:

*Method 1: Expose Service to Template*

*Pro:*

- Simple, very obvious where you're accessing the properties and methods
- Able to bind to the services properties without needing a $watch in your 
controller or using events

*Cons:*

- Verbose, your template expressions become very long due to the repetition 
of the name
- Service is coupled with templates, changes to how the service works could 
break your UI


*Method 2: Wrap Methods in Controller*

*Pro:*

- Still obvious where methods and properties come from (everything goes 
through the controller)
- Service is not coupled with the templates, if the service changes your 
controller methods can be updated without touching the templates

*Cons:*

- Verbose, everything needs to be wrapped
- Properties must be accessed through methods, increasing function calls 
during each watch cycle

* Method 3: Reassign Service Methods to Controller*

*Pros:*

- Less verbose than method 2, while keeping some separation between the 
service and the template
- Service acts more like a module with private state

*Cons:* 

- Could be unclear how things are being updated since `this` is actually 
the `this` of the controller
- Still can't bind directly to properties, state must be wrapped in 
functions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

If you've got any insight, or have tried these methods to success please 
post. Also, if I've left any ways of doing this out I can update this post.


-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to