Function in $ parsers-array not called in custom directive

I want to test a value change in a custom directive.
For this I use the parsers unshift function to add my own function

But my own function is not called!

It's my opinion:

<div ng-controller="MyCtrl">
    <form novalidate name="myForm">
        Number: <even-number name="awesomeField" ng-model="val"></even-number>
    </form>
</div>

      

This is my javasript code:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.val = "42";
    $scope.$watch('val', function() {
        console.log("Controller: "+$scope.val);
    });
}

myApp.directive('evenNumber', function(){
    var tmplt = ''+
    '<div class="input-group">'+
        '<input class="form-control" name="inputDate" type="text" data-ng-model="ngModel"/>'+
        '<span class="input-group-btn">'+
            '<button class="btn btn-default">Default</button>'+
        '</span>'+
    '</div>';
    return {
        restrict: 'E',
        require:'ngModel',
        replace: true,
        template: tmplt,
        scope: {
            ngModel: "="
        },
        link: function(scope, elem, attrs, ctrl){
            ctrl.$parsers.unshift(checkValue);

            function checkValue(viewValue){
                console.log("halllllo");
                return viewValue;
            }
        } // end link
    }; // end return
});

      

What is the problem?

Here's it as a jsFiddle

+3


source to share


1 answer


Write your directive as an attribute directive to be used on an element <input />

that ngModel knows how to handle already. Wrapping input like this won't work with ngModel. You will need two directives to achieve what you need. One that connects the input and the button (event number), and the second that attaches to the input itself to do any conversions using $ parsers model --> view

and $ formatters view --> model

.

Update Here's an example:



var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.val = "42";
    $scope.$watch('val', function() {
        console.log("Controller: "+$scope.val);
    });
}

myApp
.directive('evenNumberConverter', function(){
    return {
        restrict: 'A',
        require:'ngModel',
        link: function(scope, elem, attrs, ctrl){
            ctrl.$parsers.unshift(checkValue);
       
            function checkValue(viewValue){
                console.log("halllllo");
                return viewValue;
            }
        } // end link
    }; // end return
})
.directive('evenNumber', function(){
    var tmplt = ''+
    '<div class="input-group">'+
        '<input class="form-control" name="inputDate" type="text" even-number-converter data-ng-model="value"/>'+
        '<span class="input-group-btn">'+
            '<button class="btn btn-default" data-ng-click="setDefault()">Default</button>'+
        '</span>'+
    '</div>';
    return {
        restrict: 'E',
        replace: true,
        template: tmplt,
        scope: {
            value: "="
        },
        link: function(scope, elem, attrs, ctrl){
            scope.setDefault = function() {
              scope.value = 0;
            };
        } // end link
    }; // end return
});
      

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
    <form novalidate name="myForm">
        Number ({{val}}): <even-number name="awesomeField" value="val"></even-number>
    </form>
</div>
      

Run codeHide result


Notes: The point is that your directive does not use any of the methods ngModelController

to send the value to the view componenttent and read it back into the model. Its a simple "wrapper" directive and as such the ngModel in scope can also be called in any other way.

This is because the ngModel directive knows nothing about your "even number" element. To do this, you will have to override and use the method $render()

to represent the value and when reading from the UI, the new value is used $setViewValue()

. Only then are $ parsers and $ formatters run, otherwise the scope variable ngModel behaves like any other.

+1


source







All Articles