在输入元素中使用angularjs过滤器
我希望我没有错过任何明显的文件,如果我有,我相信有人会帮助我 我正在使用asp.net webapi返回一个带有日期字段的DTO。这些文件使用JSON.Net(格式为“2013-03-11T12:37:38.693”)进行序列化 我想使用一个过滤器,但在输入元素中,这是可能的,还是应该创建一个新的过滤器或指令来实现这一点在输入元素中使用angularjs过滤器,angularjs,asp.net-web-api,angularjs-directive,Angularjs,Asp.net Web Api,Angularjs Directive,我希望我没有错过任何明显的文件,如果我有,我相信有人会帮助我 我正在使用asp.net webapi返回一个带有日期字段的DTO。这些文件使用JSON.Net(格式为“2013-03-11T12:37:38.693”)进行序列化 我想使用一个过滤器,但在输入元素中,这是可能的,还是应该创建一个新的过滤器或指令来实现这一点 // this just displays the text value <input ui-datetime type="text" data-ng-model="en
// this just displays the text value
<input ui-datetime type="text" data-ng-model="entity.date" />
// this doesn't work at all
<input ui-datetime type="text" data-ng-model="{{entity.date|date:'dd/MM/yyyy HH:mm:ss a'}}" />
// this works fine
{{entity.date|date:'dd/MM/yyyy HH:mm:ss a'}}
//这只是显示文本值
//这根本不起作用
//这个很好用
{{entity.date}date:'dd/MM/yyyy HH:MM:ss a'}
是否有我缺少的快捷方式?您不需要从零开始创建新的筛选器,因为angular已经为日期类型提供了内置筛选器。
我相信这正是您所需要的。简而言之:如果您希望数据在视图和模型中具有不同的表示形式,则需要一个指令,您可以将其视为一个双向过滤器 你的指令看起来像
angular.module('myApp').directive('myDirective', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
ngModelController.$parsers.push(function(data) {
//convert data from view format to model format
return data; //converted
});
ngModelController.$formatters.push(function(data) {
//convert data from model format to view format
return data; //converted
});
}
}
});
HTML:
下面是一个工作示例。在输入字段和模型中具有不同的值与ng模型的本质背道而驰。因此,我建议您采用最简单的方法,在控制器内部应用过滤器,对格式化日期使用单独的变量,并雇佣观察者保持格式化日期与原始日期同步: HTML:
设置数字格式的完整示例,从结尾开始,每3个字符插入空格:
'use strict'
String::reverse = ->
@split('').reverse().join('')
app = angular.module('app', [])
app.directive 'intersperse', ->
require: 'ngModel'
link: (scope, element, attrs, modelCtrl) ->
modelCtrl.$formatters.push (input) ->
return unless input?
input = input.toString()
input.reverse().replace(/(.{3})/g, '$1 ').reverse()
modelCtrl.$parsers.push (input) ->
return unless input?
input.replace(/\s/g, '')
用法:
<input ng-model="price" intersperse/>
Plunkr示例:如果您的输入仅显示数据
如果您实际上需要一个输入来简单地显示一些信息,而改变角度模型的是另一个元素,那么您可以更轻松地进行改变
不要简单地编写新指令,而不要使用ng模型,使用好的、旧的值
因此,不是:
<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
Angular具有内置功能,但要将其应用于最终需要获取原始(未格式化)日期的输入,需要创建自定义的
指令示例:
(function () {
'use strict';
angular.module('myApp').directive('utcDate', ['$filter', function ($filter) {
return {
restrict: 'A', //restricting to (A)ttributes
require: 'ngModel',
link: function (scope, elem, attrs, model) {
if (!model) return;
var format = 'MM/dd/yyyy h:mm:ss a';
var timezone = 'UTC';
//format the date for display
model.$formatters.push(function (value) {
//using built-in date filter
return $filter('date')(value, format, timezone);
});
//remove formatting to get raw date value
model.$parsers.push(function (value) {
var date = Date.parse(value);
return !isNaN(date) ? new Date(date) : undefined;
});
}
};
}]);
})();
然后应用它:
<input type="text" ng-model="$ctrl.DateField" utc-date />
我认为创建一个新的指令来满足这些要求是一个更干净的解决方案。如果我正确理解OP的问题,你是对的。它更干净。我只是想给@leon一个选择,以防他/她还不太适应自定义指令。谢谢大家,两个答案都很受欢迎,因为学习其他方法很好。-1,双变量+观察是一个支持地狱。设想一个包含数十个变量(保险计算器等)的范围看起来不错,但您将如何应用它?具体来说,如何指定要在格式化中使用的筛选器?@PaulTaylor将此指令仅限制为“attribute”,并在输入字段中使用该属性(类似于您编写的
。还有一个更完整的示例。在JSFIDLE上运行示例?谢谢!我的解决方案中,您的示例唯一缺少的就是观察模型的变化并重新运行格式化程序。我不明白如何使用AngularJS轻松实现这一点,我必须强制元素更新:范围。$watch(attrs.ngModel,function(value){element.val($filter('number')(value,0));});
-1,OP询问了在ngModel
中使用过滤器的具体问题,这与创建新过滤器有很大的不同。modelCtrl.$parser(或格式化程序)到底有什么作用.push有什么作用?@Vincent,它向格式化程序数组中添加了一个函数,当需要显示模型中的值时调用该数组。将$formatters数组视为一个充满函数的管道,其中每个函数都被调用,结果通过管道进一步传递。调用所有函数后,将显示最终结果。$parsers是一个类似的东西,但用于向模型写入。我认为这实际上不起作用,你有一个plunker或类似的吗?很好!唯一的问题是它在任何长度为3的倍数的数字之前添加一个空格,正确的方法是仅当长度为3的倍数并且后面有另一个数字时才添加空格。它看起来不像li当您的区域设置没有将数字分隔符定义为点(
)时会出现一个问题,它看起来是这样的:.999
PS.:使用$filter('number');
似乎是一种更好的方法,它通过$locale
服务加载格式,并且您可以使用新的RegExp(\\”+$locale.number\u FORMATS.GROUP\u SEP,'g'));
要将值反转为模型。。。
<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
<input value="{{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
(function () {
'use strict';
angular.module('myApp').directive('utcDate', ['$filter', function ($filter) {
return {
restrict: 'A', //restricting to (A)ttributes
require: 'ngModel',
link: function (scope, elem, attrs, model) {
if (!model) return;
var format = 'MM/dd/yyyy h:mm:ss a';
var timezone = 'UTC';
//format the date for display
model.$formatters.push(function (value) {
//using built-in date filter
return $filter('date')(value, format, timezone);
});
//remove formatting to get raw date value
model.$parsers.push(function (value) {
var date = Date.parse(value);
return !isNaN(date) ? new Date(date) : undefined;
});
}
};
}]);
})();
<input type="text" ng-model="$ctrl.DateField" utc-date />