对类型为ngModel的对象使用$formatter,角度为1.2,但版本为1.3

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

本文关键字:版本 ngModel 类型 对象 formatter      更新时间:2023-09-26

此代码适用于angular-1.2.26,但不适用于angular 1.3.0.rc5(或我尝试过的任何1.3.x版本)。

我发现了这个问题https://github.com/angular/angular.js/issues/9218在angular的github上,但我不熟悉github接口,我不知道这个错误是否被确认,或者行为是否是预期的,是否已经修复;如果是,我应该选择什么版本。

JSFiddles:

  • angular v1.2.26,ngModel为对象
  • angular v1.3..rc5,ngModel为对象

对于每一个,我希望在加载页面时在输入中都有"我的标签"。它适用于第一个,但不适用于第二个。

然后查看控制台,查看传递给格式化程序的值。

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.3中,您应该这样做(这在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;
            })
        }
    }
})

因为如果你在1.3中unshift你的$formatter,那么你会得到模型的字符串值,如果你想访问模型的非字符串值,你必须把$formatter放在最后(push)。

我知道这与伊戈尔·米纳尔的评论相矛盾。

突破性的变化是,传递到格式化程序中的viewValue将是格式化的modelValue的toString版本。所以,如果有任何习俗格式化程序在默认格式化程序之后执行,它们将看到字符串值的版本。如果任何格式化程序需要访问该值在字符串化之前,格式化程序应该通过$formatters.unshift(customFormatter).

在那条评论之后,情况发生了变化

示例