Building Your Own Directives
Searching for parents for the controller
If the directive, whose controller you require, can appear on this or any ancestor
of the current element, then you can put a '^' in front of the directive name,
for example, require: '^ngModel'. The compiler will then search the ancestor
elements starting from the element containing the current directive and return the
first matching controller.
You can combine optional and ancestor prefixes to have an optional
directive that may appear in an ancestor. For example, require:
'^?form' would let you find the controller for the form directive,
which is what the ng-model directive does to register itself with the
form if it is available.
Working with ngModelController
Once we have required the ngModelController we use its API to specify the
validity of the input element. This is a common case for this kind of directive and
the pattern is fairly straightforward. The ngModelController exposes the following
functions and properties that we will use:
Name Description
$parsers A pipeline of functions that will be called
in turn when the value of the input element
changes.
$formatters A pipeline of functions that will be called in
turn when the value of the model changes.
$setValidity(validationError
Key, isValid)
A function called to set whether the model is
valid for a given kind of validation error.
$valid True if there is no error.
$error An object that contains information about
any validation errors on the model.
The functions that go into $parsers and $formatters take a value and return a
value, for example, function(value) { return value; }. The value they receive
is the value returned from the previous function in the pipeline. It is inside these
functions where we put our validation logic and call $setValidity().