Use a directive to augment a DOM
node:
- To transform its contents in a regular manner.
- To add a behaviour that is general and reusable.
Do not use a directive:
- To augment or manipulate shared
scope
(use acontroller
instead). - To allow a partial to include another partial specific to your application (this is not composable, use nested states instead).
Directives are invoked using hypenated-lowercase
but are mapped as camelCase
. Their factory is a method so is also camelCase
. Meaning:
angular.module(...).directive('myDirective', myDirective);
And in HTML:
<div my-directive></div>
Injection is available at the top of the directive only in its function definition. This must be annotated with the @ngInject
doctag.
There is no dependency injection in link()
. Consequently you cannot change the order of parameters in the link()
method.
Use any combination of the restrict
characters; A
ttribute name, E
lement name, CSS C
lass name.
Use either template
or templateUrl
but not both. The template must not be specific to your use case.
If you need specific content then use transculusion
, meaning:
replace: true,
transclude: true,
template: '<div ng-transclude></div>',
The replace
option relates to the HTML node in which you apply your directive. Generally you will want this node to only comprise your template (any any transcluded content). However when using replace: false
your template will appear first, before the existing content.
Your directive should have a well defined dependency on your document. Start with scope: { }
to isolate your scope.
Do not use a controller()
function, use a link()
function instead.
Pass parameters explicitly through attributes
. Attributes are a parameter of the link()
function, or may be coppied to the isolated scope; @
implies string initialisation, =
implies 2-way string binding, &
implies a function that evaluates the attribute as a statement.
If you need to expose an API, and only in this case, use a Class
for the controller
property. Meaning controller: MyController
(as the definition not as a string). This will be instantiated. Other directives may require
your directive and will receive this instance as an additional parameter in its link()
method. See the angular docs for full details.
The driver of complexity in the directive is the link()
function. Where your link function is simple then write it in-line. However if it is complex then make it an external Class
.