模型格式化和解析器

我以不同的形式提出了同样的问题,但是没有人回答。我不清楚 Formatter 和 Parser 在带角度的 js 中做什么。

根据定义,Formatter 和 Parser 看起来与我很相似。也许我错了,因为我是新来的。

格式事项定义

当模型值发生更改时,作为管道执行的函数数组。 依次调用每个函数,将值传递给下一个函数。 用于格式化/转换值以便在控件和验证中显示。

解析器定义

每当控件从 DOM 读取值时,作为管道执行的函数数组。 依次调用每个函数,将值传递给下一个函数。 用于消毒/转换值以及验证。 对于验证,解析器应该使用 $setVality ()更新有效性状态,并返回未定义的无效值。

请用一个简单的例子来帮助我理解这两个特性。

100466 次浏览

This topic was covered really well in a related question: How to do two-way filtering in AngularJS?

To summarize:

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

Here is a simple example, building on an example in the 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();
});

You can see it in action: 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" />

When you type a name in (view to model), you will see that the model is always lowercase. But, when you click a button and programatically change the name (model to view), the input field is always uppercase.

Another usage for formatters and parsers is when you want to store dates in UTC time and display them in local time on inputs, I created the below datepicker directive and utcToLocal filter for this.

(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();
});
}
};
}
})();

It uses this utcToLocal filter that ensures the input date is in the correct format before converting to local time.

(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 is used to convert local to utc dates.

pickadate.js is the datepicker plugin used