ngModel and How it is Used

前端 未结 1 367
闹比i
闹比i 2021-01-15 17:17

I am just getting started with angular and ran into the directive below. I read a few tutorials already and am reading some now, but I really don\'t understand what \"requir

相关标签:
1条回答
  • 2021-01-15 17:27

    ngModel is an Angular directive responsible for data-binding. Through its controller, ngModelController, it's possible to create directives that render and/or update the model.

    Take a look at the following code. It's a very simple numeric up and down control. Its job is to render the model and update it when the user clicks on the + and - buttons.

    app.directive('numberInput', function() {
      return {
        require: 'ngModel',
        restrict: 'E',
        template: '<span></span><button>+</button><button>-</button>',
        link: function(scope, element, attrs, ngModelCtrl) {
          var span = element.find('span'),
              plusButton = element.find('button').eq(0),
              minusButton = element.find('button').eq(1);
    
          ngModelCtrl.$render = function(value) {
            updateValue();
          };
    
          plusButton.on('click', function() {
            ngModelCtrl.$setViewValue(ngModelCtrl.$modelValue + 1);
            updateValue();
          });
    
          minusButton.on('click', function() {
            ngModelCtrl.$setViewValue(ngModelCtrl.$modelValue - 1);
            updateValue();
          });
    
          function updateValue(value) {
            span.html(ngModelCtrl.$modelValue);
          }
        }
      };
    });
    

    Working Plunker

    Since it interacts with the model, we can use ngModelController. To do that, we use the require option to tell Angular we want it to inject that controller into the link function as its fourth argument. Now, ngModelController has a vast API and I won't get into much detail here. All we need for this example are two methods, $render and $setViewValue, and one property, $modelValue.

    $render and $setViewValue are two ways of the same road. $render is called by Angular every time the model changes elsewhere so the directive can (re)render it, and $setViewValue should be called by the directive every time the user does something that should change the model's value. And $modelValue is the current value of the model. The rest of the code is pretty much self-explanatory.

    Finally, ngModelController has an arguably shortcoming: it doesn't work well with "reference" types (arrays, objects, etc). So if you have a directive that binds to, say, an array, and that array later changes (for instance, an item is added), Angular won't call $render and the directive won't know it should update the model representation. The same is true if your directive adds/removes an item to/from the array and call $setViewValue: Angular won't update the model because it'll think nothing has changed (although the array's content has changed, its reference remains the same).

    This should get you started. I suggest that you read the ngModelController documentation and the official guide on directives so you can understand better how this all works.

    P.S: The directive you have posted above isn't using ngModelController at all, so the require: 'ngModel' line is useless. It's simply accessing the ng-model attribute to get its value.

    0 讨论(0)
提交回复
热议问题