0

I have an usecase where I need to dynamically add directives to an input field, depending on the configuration set in a DB. It all seemed to work fine, but there were some strange quirks with these input fields. I discovered that the strange behaviour is caused by the directives calling the formatters when I expect them to call the parsers.

I made a plunker to demonstrate this behaviour.

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

app.controller('MainCtrl', function($scope) {
    $scope.test1 = 'World1';
    $scope.test2 = 'World2';
});

app.directive('test', ['$log', function($log) {
    return {
        require : 'ngModel',
        link : function(scope, elm, attrs, ctrl) {
            function parse(viewValue) {
                console.log('parsing', viewValue);
                return viewValue;
            }

            function format(viewValue) {
                console.log('formatting', viewValue);
                return viewValue;
            }

        ctrl.$formatters.unshift(format);
        ctrl.$parsers.unshift(parse);
        }
    };
}]);

app.directive('variabele', ['$compile', function($compile) {
    return {
        restrict : 'E',
        template : '<div><input ng-model="ngModel" /></div>',

        scope : {
            ngModel : '='
        },
        require: ['ngModel'],

        link: function(scope, elm, attrs, ctrl) {
            console.log('testing');
            var input = angular.element(elm.find("input"));
            input.attr('test', '');

            $compile(input)(scope);
        }
    };
}]);

plunker

It's a bit simplified from what I have to illustrate the problem. There are two input fields. One of which always has the test directive. The other has the variable directive which in turn adds the test directive dynamically.

In reality one or more directives are added which are defined in the database. When you change the value of the first input field you can see in tghe console that the parser is called, but when you change the value of the second input field you see that the formatter is being called instead. I'm not sure what I'm doing wrong here.

EDIT: The original plunker was broken, so i fixed it. They now use a different model for each input field and the second input field correctly uses the variabele directive.

Benne Otten
  • 31
  • 1
  • 5
  • First you have to fix the plunkr to really inlustrate the problem - for now your plunkr actually doesn't even get to show in console the `console.log('testing');` execution. – Diana R May 03 '16 at 12:17
  • You're right. The plunker was broken, my apologies. I fixed it to demonstrate the problem – Benne Otten May 04 '16 at 07:18

1 Answers1

0

It is the expected behaviour,

  • Formatters change how model values will appear in the view.
  • Parsers change how view values will be saved in the model.

In your case, you bind the same value in both directive test and variabele. when you change value in test directive parsers are called ( view -> model) and in variabele it is the other way (model -> view) formatters are called.

for more info: How to do two-way filtering in angular.js?

Community
  • 1
  • 1
srinivasan
  • 685
  • 9
  • 18
  • The plunker changed a bit after this answer because it was broken. Is the problem occuring because of this reason? I don't see why it should, but maybe I'm missing something. – Benne Otten May 10 '16 at 14:45
  • no, It is the way angular works. to elaborate, if you keep the parsers and formatters in the variabele directive as well you can notice when the value is changed in test directive the formatters will be called in the variabele directive and when the value is changed in variabele directive the parsers will be called in the variabele directive and vice versa for test. – srinivasan May 11 '16 at 08:24
  • The thing is that both input fields have the test directive. The difference is that it's set dynamically in the second one. – Benne Otten May 11 '16 at 09:04