Use a $formatter on a object typed ngModel value with angular 1.2 worked, but not with version 1.3

牧云@^-^@ 提交于 2019-12-07 08:42:33

问题


This code worked with angular-1.2.26, but not with angular-1.3.0.rc5 (or any 1.3.x versions I tried).

I found this issue https://github.com/angular/angular.js/issues/9218 on angular's github, but I am not familiar with github interface and I cannot figure out if the bug is confirmed or if the behavior is expected, if it has been fixed or not; and if yes, what version should I take.

JSFiddles :

  • with angular v1.2.26, ngModel as object
  • with angular v1.3.0.rc5, ngModel as object

For each, I expect to have 'my label' in the input when loading the page. It works for the first one, but not for the second.

And look at the console to see what value is passed to the formatter.

HTML :

<div ng-controller="ctrl as c">
    <input my-dir ng-model="c.foobar" />
    <pre>{{c.foobar | json}}</pre>
</div>

JS :

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

app.controller('ctrl', function(){
    this.foobar = {
        value : 'my value',
        label : 'my label'
    }
})


.directive('myDir', function(){
    return {
        restrict :'A',
        require:'ngModel',
        link : function(scope, elt, attrs, modelCtrl){

            // conversion "view -> model"
            modelCtrl.$parsers.unshift( function(value){
                console.log('Value:', value);
                return {label:value, value:value};
            })

            // conversion "model -> view"
            modelCtrl.$formatters.unshift(function formatter(modelValue){
                console.log('modelValue:', modelValue);
                return modelValue.label;
            })
        }
    }
})

回答1:


In 1.3 you should be doing it like this (which will also work in 1.2):

.directive('myDir', function(){
    return {
        restrict :'A',
        require:'ngModel',
        link : function(scope, elt, attrs, modelCtrl){

            // conversion "view -> model"
            modelCtrl.$parsers.push( function(value){
                console.log('Value:', value);
                return {label:value, value:value};
            })

            // conversion "model -> view"
            modelCtrl.$formatters.push(function formatter(modelValue){
                console.log('modelValue:', modelValue);
                return modelValue.label;
            })
        }
    }
})

Because if you unshift your $formatter in 1.3, then you will get the stringified value of the model, if you want to have access to the non stringified value of the model, you will have to put your $formatter at the end (push).

I know that this contradicts this comment of Igor Minar.

The breaking change is that the viewValue passed into formatters will be a toString version of the formatted modelValue. So if any custom formatters execute after the default formatter, they'll see the string version of the value. If any formatter needs access to the value before it was stringified, the formatter should be registered via $formatters.unshift(customFormatter).

But things changed after that comment.

Example



来源:https://stackoverflow.com/questions/26564986/use-a-formatter-on-a-object-typed-ngmodel-value-with-angular-1-2-worked-but-no

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!