Monday, December 21, 2015

Using require: 'ngModel' in your angular directives

The require instruction gives you the controller for the directive you name as the fourth argument to your link function. (You can use ^ to look for the controller on a parent element; ? makes it optional.) So require: 'ngModel' gives you the controller for the ngModel directive, which is an ngModelController.
Directive controllers can be written to provide APIs that other directives can use; with ngModelController, you get access to special functionality that's built into ngModel, including getting and setting the value. Consider the following example:
<input color-picker ng-model="project.color">
app.directive('colorPicker', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      element.colorPicker({
        // initialize the color to the color on the scope
        pickerDefault: scope.color,
        // update the ngModel whenever we pick a new color
        onColorChange: function(id, newValue) {
          scope.$apply(function() {
            ngModel.$setViewValue(newValue);
          });
        }
      });

      // update the color picker whenever the value on the scope changes
      ngModel.$render = function() {
        element.val(ngModel.$modelValue);
        element.change();                
      };
    }
  }
});
This directive uses the ngModel controller to get and set the value of the color from the colorpicker. See this JSFiddle example: http://jsfiddle.net/BinaryMuse/AnMhx/
If you're using require: 'ngModel', you probably shouldn't also be using ngModel: '=' in your isolate scope; the ngModelController gives you all the access you need to change the value.
The bottom example on the AngularJS homepage also uses this functionality (except using a custom controller, not ngModel).

As for the casing of a directive, for example, ngModel vs ng-model vs data-ng-model: while Angular supports using multiple forms on the DOM, when you refer to a directive by name (for example, when creating a directive, or using require), you always use the lowerCamelCase form of the name.

No comments:

Post a Comment