$commitViewValue and ngModel.ngModelController all properties and methods

how view value and model value are changing and how we can configure them

HTML

<div ng-app="myApp">
  <div ng-controller="myController">
  <p>{{hell}} Welcome message </p>
  <form name="formDemo">
  
    Debounce Demo(Check Console) : <input type="text" ng-model="name" 
    ng-init="name='samar'" name="nameInput"
    ng-model-options="{debounce:300,updateOn:'blur'}" placeholder="Type here..." 
    ng-keyup="checkESC($event)" my-directive/>
    <span ng-show="formDemo.nameInput.$error.invalidName">Name Cant contain '@'</span>
  </form>
   <p>
      {{name}}
      </p>
  </div>
  </div>

JavaScript

var app = angular.module("myApp", []);
app.controller("myController", function($scope){
	$scope.hell="hell it is :(";
  $scope.checkESC= function(e){
  	console.log(e.type)
    //force to call $commitViewValue() before input is blurred
    if(e.keyCode==13){
    	$scope.formDemo.nameInput.$commitViewValue();
    }
    //this below line will override "updateOn:'blur'", will not wait till the input is blurred and update the value after each keyUp and     $$lastCommittedViewValue will set
    //$scope.formDemo.nameInput.$commitViewValue();//A 
    
    //model value "name" will not change untill the input is blurred
    console.log(`Model value :${$scope.formDemo.nameInput.$modelValue}`)
    
    //view value will be changing as we start typing 
    console.log(`View	 value :${$scope.formDemo.nameInput.$viewValue}`)
    
  	if(e.keyCode==27){
    	console.log("ESC pressed")
      console.log($scope.formDemo.nameInput)
      //when we are writting "updateOn" in ngModelOptions , its calls $commitViewValue implicitly
      //when we are epressing ESC, till then only view is updating , not the model.after pressing ESC viewvalue is rollbacked to $$lastCommittedViewValue
    	//line B1 is not manadatory, but better to keep it always to render the input control with last committed value.
      
      $scope.formDemo.nameInput.$rollbackViewValue();//B
      $scope.formDemo.nameInput.$render();//B1
      console.log($scope.formDemo.nameInput.$$lastCommittedViewValue);
      
    }
  }
});
app.directive("myDirective", function(){
	return {
  	restrict:"EA",
    require:"ngModel",
    link: function(scope,ele,attr,ctrl){
    	var retValue;
    	ctrl.$parsers.push(function(value){
      	ctrl.$commitViewValue();
      	if(value.indexOf("@") > -1){        	
        	ctrl.$setValidity("invalidName", false);
        }else{        	
        	ctrl.$setValidity("invalidName", true);
        }
        return value;
      })
    }
  }
})