Use a controller to augment shared scope
.
- To decorate it with
value
that HTMLpartials
may bind to. - To provide
behaviour
that HTMLpartials
may invoke.
Do not use a controller:
- To store application state (describe in the
route
instead). - To store persistent data (controllers and scope are dropped on every route change, use
service
instead). - To implement behaviour and business logic (defer to a
service
).
In angular, controllers are implemented as a Class
. Angular will resolve the dependency as a class and then new
that class. Therefore the mapping should be PascalCase
as well as the classname itself. For example:
angular.module(...).controller('MyController', MyController);
In our implementation you can effectively assume that scope instanceof controller
. This is because in our constructor
we will extend()
the scope with the members of the instance.
Extend is a method that will copy members of one object to another. It was popularised by jQuery.extend() but we require a different implementation that will copy accessors (get/set) correctly.
We will therefore need to bind()
these members (accessors and functions) to ensure that their this
reference is not lost.
In javascript instance methods can easily loose their
this
reference. We can leverage Function.bind() method can to bind all functions and accessors of a given object.
The controller is somewhat similar to the directive link()
method. An external link implementation should look exactly like a controller but may inject element
and attributes
.
Behaviour should follow the flyweight pattern. Meaning that functions should gather operands from the scope
and delegate to a method on a service
. It should not implement the operation directly.
Injection is available in the constructor only. This must be annotated with the @ngInject
doctag.
Firstly bind
the instance and extend
scope.
Initialise any private
properties.
Add watch
statements. Handlers may be organised as members of the class, or may be anonymous.
Public properties
(i.e. variables) are not permitted. Use accessors, meaning getter
and/or setter
methods.
The function
keyword is not needed.
The 'use strict'
statement is not needed.
Private properties should have the same name as any public property that it shadows. A trailing underscore is required per google javascript style.