首页 文章

ngModel格式化程序和解析器

提问于
浏览
97

我以不同的形式发布了同样的问题,但没有人回答 . 我没有清楚地了解格式化程序和解析器在角度js中的作用 .

根据定义,Formatters和Parsers看起来与我类似 . 也许我错了,因为我是这个angularjs的新手 .

格式化程序定义

每当模型值发生变化时,作为管道执行的函数数组 . 反过来,每个函数都被调用,将值传递给下一个函数 . 用于格式化/转换值以在控件和验证中显示 .

解析器定义

每当控件从DOM读取值时,作为管道执行的函数数组 . 反过来,每个函数都被调用,将值传递给下一个函数 . 用于清理/转换值以及验证 . 对于验证,解析器应使用$ setValidity()更新有效性状态,并为无效值返回undefined .

请通过一个简单的例子帮助我理解这两个功能 . 两者的简单说明将不胜感激 .

2 回答

  • 149

    在一个相关问题中很好地介绍了这个主题:How to do two-way filtering in AngularJS?

    总结一下:

    • 格式化程序更改模型值在视图中的显示方式 .

    • 解析器更改视图值在模型中的保存方式 .

    这是一个简单的例子, Build 在NgModelController api documentation中的一个例子:

    //format text going to user (model to view)
      ngModel.$formatters.push(function(value) {
        return value.toUpperCase();
      });
    
      //format text from the user (view to model)
      ngModel.$parsers.push(function(value) {
        return value.toLowerCase();
      });
    

    你可以看到它的实际效果:http://plnkr.co/UQ5q5FxyBzIeEjRYYVGX?plnkr=legacy

    <input type="button" value="set to 'misko'" ng-click="data.name='misko'"/>
    <input type="button" value="set to 'MISKO'" ng-click="data.name='MISKO'"/>
    <input changecase ng-model="data.name" />
    

    在(查看模型)中键入名称时,您将看到模型始终为小写 . 但是,当您单击按钮并以编程方式更改名称(要查看的模型)时,输入字段始终为大写 .

  • 5

    格式化程序和解析器的另一种用法是,当您希望以UTC时间存储日期并在输入时以本地时间显示它时,我为此创建了以下datepicker指令和utcToLocal过滤器 .

    (function () {
        'use strict';
    
        angular
            .module('app')
            .directive('datepicker', Directive);
    
        function Directive($filter) {
            return {
                require: 'ngModel',
                link: function (scope, element, attr, ngModel) {
                    element.addClass('datepicker');
                    element.pickadate({ format: 'dd/mm/yyyy', editable: true });
    
                    // convert utc date to local for display
                    ngModel.$formatters.push(function (utcDate) {
                        if (!utcDate)
                            return;
    
                        return $filter('utcToLocal')(utcDate, 'dd/MM/yyyy');
                    });
    
                    // convert local date to utc for storage
                    ngModel.$parsers.push(function (localDate) {
                        if (!localDate)
                            return;
    
                        return moment(localDate, 'DD/MM/YYYY').utc().toISOString();
                    });
                }
            };
        }
    })();
    

    它使用此utcToLocal过滤器确保输入日期在转换为本地时间之前的格式正确 .

    (function () {
        'use strict';
    
        angular
            .module('app')
            .filter('utcToLocal', Filter);
    
        function Filter($filter) {
            return function (utcDateString, format) {
                if (!utcDateString) {
                    return;
                }
    
                // append 'Z' to the date string to indicate UTC time if the timezone isn't already specified
                if (utcDateString.indexOf('Z') === -1 && utcDateString.indexOf('+') === -1) {
                    utcDateString += 'Z';
                }
    
                return $filter('date')(utcDateString, format);
            };
        }
    })();
    

    moment.js用于将本地转换为utc日期 .

    pickadate.js是使用的datepicker插件

相关问题