ngModel 格式化程序和解析器
Posted
技术标签:
【中文标题】ngModel 格式化程序和解析器【英文标题】:ngModel Formatters and Parsers 【发布时间】:2014-05-15 11:50:55 【问题描述】:我以不同的形式发布了相同的问题,但没有人回答。我没有清楚地了解格式化程序和解析器在 Angular js 中的作用。
根据定义,格式化程序和解析器看起来都与我相似。也许我错了,因为我是这个 angularjs 的新手。
格式化程序定义
每当模型值发生变化时,作为管道执行的函数数组。 依次调用每个函数,将值传递给下一个函数。 用于格式化/转换值以在控件中显示和验证。
解析器定义
每当控件从 DOM 读取值时,作为管道执行的函数数组。 依次调用每个函数,将值传递给下一个函数。 用于清理/转换值以及验证。 对于验证,解析器应该使用 $setValidity() 更新有效性状态,并为无效值返回 undefined。
请通过一个简单的示例帮助我理解这两个功能。两者的简单说明将不胜感激。
【问题讨论】:
格式化程序修改模型的显示值,例如为电话号码显示(123) 123-1234
。解析器在每次数据更改时读取数据,通常用于设置输入的 $valid 状态。文档中有这两种情况的示例。
【参考方案1】:
一个相关问题很好地涵盖了这个主题:How to do two-way filtering in AngularJS?
总结一下:
格式化程序更改模型值在视图中的显示方式。 解析器更改视图值在模型中的保存方式。这是一个简单的例子,建立在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" />
当您在(视图到模型)中输入名称时,您会看到模型始终是小写的。但是,当您单击按钮并以编程方式更改名称(要查看的模型)时,输入字段始终为大写。
【讨论】:
有没有办法在用户键入时设置此更改?你说“以编程方式”,但我试图让 $viewValue 在用户输入输入时被格式化,例如信用卡号格式化 @SavvasNicholas 如果我没记错的话,你会使用ngModel.$setViewValue(transformedInput);
来设置它并使用 ngModel.$render();
从 $parsers 函数中渲染它。
就我而言,$formatters
所做的事情会立即被$validators
还原。 ;(
仅供参考,引用的 plunkr 不再存在
我注意到格式化程序只有在您按下按钮时才有效,如果您在字段中输入名称则无效【参考方案2】:
格式化程序和解析器的另一种用法是,当您想以 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 是使用的日期选择器插件
【讨论】:
以上是关于ngModel 格式化程序和解析器的主要内容,如果未能解决你的问题,请参考以下文章