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.