Explicitly providing ng-model to DOM elements

28 / Jul / 2014 by Sakshi Tyagi 1 comments

angularjs

In AngularJS, we can easily write our own custom directives to achieve required functionality. There are certain attributes which we provide in directive definition like restrict , scope , template, link, transclude etc.

There is one more attribute named : require , which gives us the liberty to include another directive and inject its controller as the fourth argument to the linking function. It accept both string as well as array type. In case of array, the controllers are included in the given order. There are some prefixes, when applied before controller name, provides different functionality:

  • 1. Without prefix – Locate the required controller on the current element. Throw an error if not found.
  • 2. (?) – Attempt to locate the required controller or pass null to the link function if not found.
  • 3. (^) – Locate the required controller by searching the element’s parents. Throw an error if not found.
  • 4. (?^) – Attempt to locate the required controller by searching the element’s parents or pass null to the link function if not found.

Lets understand it with an example. We have a <div> and we want to assign ng-model to it which is not provided in angular by default. So, we write a custom directive for it and implement the required task inside it.

angular.module('demoApp', []).directive('contenteditable', function() {
    return {
      restrict: 'A',
      require: '?ngModel',
      link: function(scope, element, attrs, ngModelCntrl) {
        if(!ngModel) return;

        ngModel.$render = function() {
          element.html(ngModel.$viewValue || '');
        };

        element.bind('keyup', function() {
          scope.$apply(write);
        });
        write();

        function write() {
          ngModel.$setViewValue(element.html());
        }
      }
    };
});

The html file will use this directive like:

<div id="contentBox" style='height: 55px'>

</div>

Here, we provide ngModel in require attribute and therefore we get ngModelCntrl as fourth augument which is an instance of the required NgModelController( built-in controller to handle setting our model value).

There are various functions related to NgModelController like $viewValue(), $modelValue(), $setViewValue() etc, which help us to play with it.

So, in this way we can explicitly provide ng-model to those DOM elements for which angular donot implicitly provide ng-model like all input elements.

Hope it helps :-)

FOUND THIS USEFUL? SHARE IT

comments (1 “Explicitly providing ng-model to DOM elements”)

Leave a comment -