Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the meaning of require: 'ngModel'?

Tags:

angularjs

People also ask

What is mean ngModel?

ngModel is a directive which binds input, select and textarea, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during validations in a form.

How do you write ngModel?

With the ng-model directive you can bind the value of an input field to a variable created in Angular. The binding goes both ways. If the user changes the value inside the input field, the Angular property will also change its value. The ngmodel directive is not part of the Angular Core library.


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.


As stated in the Creating Custom Directives documentation: (Firstly to your question in the comment)

Can I have a data-ng-model instead?

The answer:

Best Practice: Prefer using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool, you can instead use the data-prefixed version (e.g. data-ng-bind for ngBind). The other forms shown above are accepted for legacy reasons but we advise you to avoid them.

Examples:

<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>

Secondly, what does the ?ngModel represent?

// Always use along with an ng-model
require: '?ngModel',

When using your directive, it forces it to be used along with the attribute/controller ng-model.

The require setting

(Extract from the book AngularJS by Brad Green & Shyam Seshadri)

Other directives can have this controller passed to them with the require property syntax. The full form of require looks like:

require: '^?directiveName'

Options:

  1. directiveName

    This camel-cased name specifies which directive the controller should come from. So if our <my-menuitem> directive needs to find a controller on its parent <my-menu>, we’d write it as myMenu.

  2. ^

    By default, Angular gets the controller from the named directive on the same element. Adding this optional ^ symbol says to also walk up the DOM tree to find the directive. For the example, we’d need to add this symbol; the final string would be ^myMenu.

  3. ?

    If the required controller is not found, Angular will throw an exception to tell you about the problem. Adding a ? symbol to the string says that this controller is optional and that an exception shouldn’t be thrown if not found. Though it sounds unlikely, if we wanted to let <my-menu-item>s be used without a <mymenu> container, we could add this for a final require string of ?^myMenu.


The require:'ngModel' and require:'^ngModel' allow you to inject the model attached to the element or its parent element on which the directive is bound to.

Its basically an easiest way to pass ngModel into the link/compile function instead passing it using a scope option. Once you have access to ngModel, you can change its value using $setViewValue, make it dirty/clean using $formatters, apply watchers, etc.

Below is a simple example to pass ngModel and change its value after 5 seconds.

Demo: http://jsfiddle.net/t2GAS/2/

myApp.directive('myDirective', function($timeout) {
  return {
    restrict: 'EA',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
        ngModel.$render = function() {
            $timeout(function() {
                ngModel.$setViewValue('StackOverflow');  
            }, 5000);                
        };
    }
  };
});