74

我希望我没有错过 doco 中的任何明显内容,如果我有,我相信有人会提供帮助。

我正在使用 asp.net webapi 返回一个带有日期字段的 DTO。这些是使用 JSON.Net 序列化的(格式为“2013-03-11T12:37:38.693”)。

我想使用一个过滤器,但在一个 INPUT 元素中,这是否可能或者我应该创建一个新的过滤器或指令来完成这个?

// 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'}}

有没有我错过的捷径?

4

6 回答 6

131

简而言之:如果您希望数据在视图和模型中具有不同的表示形式,您将需要一个指令,您可以将其视为双向过滤器

你的指令看起来像

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:

<input my-directive type="text" data-ng-model="entity.date" /> 

这是一个有效的jsFiddle示例。

于 2013-03-11T18:49:15.780 回答
20

在输入字段和模型中使用不同的值违背了 ng-model 的本质。所以我建议你采取最简单的方法,在控制器中应用你的过滤器,使用一个单独的变量来格式化日期,并使用观察者来保持格式化日期和原始日期同步:

HTML:

<input ui-datetime type="text" data-ng-model="formattedDate" />

JS:

app.controller('AppController', function($scope, $filter){

  $scope.$watch('entity.date', function(unformattedDate){
    $scope.formattedDate = $filter('date')(unformattedDate, 'dd/MM/yyyy HH:mm:ss a');
  });

  $scope.$watch('formattedDate', function(formattedDate){
    $scope.entity.date = $filter('date')(formattedDate, 'yyy/MM/dd');
  });

  $scope.entity = {date: '2012/12/28'};

});
于 2013-03-11T19:05:33.393 回答
16

如果您的输入仅显示数据

如果您确实需要一个输入来简单地显示一些信息,并且它是一些其他元素会更改Angular 模型,那么您可以进行更轻松的更改。

与其编写新指令,不如简单地不要使用ng-modeland 使用 good, old value

所以而不是:

<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" /> 

这将做:

<input value="{{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" /> 

就像一个魅力:)

于 2015-09-10T15:13:14.983 回答
3

格式化数字的完整示例,每 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 示例:http ://plnkr.co/edit/qo0h9z

于 2013-09-19T06:44:25.880 回答
0

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 />
于 2018-04-09T19:50:43.700 回答
-3

您不需要从零开始创建新的过滤器,因为 Angular 已经为日期类型提供了内置过滤器。 http://docs.angularjs.org/api/ng.filter:date

我相信这正是你所需要的。

于 2013-03-11T16:26:44.800 回答