如何使用ng-model格式化日期?

时间:2013-01-23 07:35:18

标签: angularjs

我有一个输入定义为

<input class="datepicker" type="text" ng-model="clientForm.birthDate" />

哪个被装配在页面的其他地方显示:

<tr>
    <th>Birth Date</th>
    <td>{{client.birthDate|date:'mediumDate'}}</td>
</tr>

当页面加载时,出生日期的格式很好,如Dec 22, 2009。但是,当我查看显示为<input>的{​​{1}}时,我猜是JS将Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time)个对象呈现为字符串。

首先,如何告诉Angular在Date中显示<input>之类的日期?我似乎无法在12/22/2009属性中应用|filters

其次,只要我编辑日期,即使将其保留为原始格式,我的其他文字(ng-model内)似乎也不会应用{{1} }过滤器;它突然改变格式以匹配输入文本框的格式。如何在每次模型更改时应用<td>过滤器?


相关问题:

9 个答案:

答案 0 :(得分:69)

使用表单的自定义验证http://docs.angularjs.org/guide/forms演示:http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

使用格式化程序和解析器以及MomentJS

的指令
angModule.directive('moDateInput', function ($window) {
    return {
        require:'^ngModel',
        restrict:'A',
        link:function (scope, elm, attrs, ctrl) {
            var moment = $window.moment;
            var dateFormat = attrs.moDateInput;
            attrs.$observe('moDateInput', function (newValue) {
                if (dateFormat == newValue || !ctrl.$modelValue) return;
                dateFormat = newValue;
                ctrl.$modelValue = new Date(ctrl.$setViewValue);
            });

            ctrl.$formatters.unshift(function (modelValue) {
                if (!dateFormat || !modelValue) return "";
                var retVal = moment(modelValue).format(dateFormat);
                return retVal;
            });

            ctrl.$parsers.unshift(function (viewValue) {
                var date = moment(viewValue, dateFormat);
                return (date && date.isValid() && date.year() > 1950 ) ? date.toDate() : "";
            });
        }
    };
});

答案 1 :(得分:35)

这是非常方便的指令angular-datetime。 您可以像这样使用它:

<input type="text" datetime="yyyy-MM-dd HH:mm:ss" ng-model="myDate">

它还会为您的输入添加遮罩并执行验证。

答案 2 :(得分:8)

我创建了一个简单的指令,使标准input[type="date"]表单元素能够与AngularJS~1.2.16一起正常工作。

看这里: https://github.com/betsol/angular-input-date

这是演示: http://jsfiddle.net/F2LcY/1/

答案 3 :(得分:7)

由于你使用了datepicker作为一个类,我假设你正在使用一个Jquery datepicker或类似的东西。

有一种方法可以在不使用moment.js的情况下完成您的意图,纯粹只使用datepicker和angularjs指令。

我在这个Fiddle

中给出了一个例子

摘自这里的小提琴:

  1. Datepicker具有不同的格式,并且angularjs格式不同,需要找到适当的匹配,以便在控件中预选日期,并且在绑定ng模型时也在输入字段中填充日期。以下格式等同于AngularJS的'mediumDate'格式。

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
    
  2. 日期输入指令需要有一个临时字符串变量来表示人类可读的日期形式。

  3. 页面的不同部分的刷新应通过$broadcast$on等事件进行。

  4. 在ng-model中也可以使用过滤器以人类可读的形式表示日期,但也可以使用临时模型变量。

    $scope.dateValString = $filter('date')($scope.dateVal, 'mediumDate');
    

答案 4 :(得分:7)

我正在使用jquery datepicker来选择日期。我的指令读取日期并将其转换为json日期格式(以毫秒为单位)存储在client_timeout数据中,同时显示格式化日期。如果ng-model具有json日期(以毫秒为单位),我的格式化程序以我的格式显示为jquery datepicker 。

Html代码:

queryResult = dbContext.Database
    .SqlQuery<int>("SELECT Max(Id) from PROPERTY ")
    .Single();

Angular Directive:

ng-model

答案 5 :(得分:6)

我使用以下指令让我和大多数用户非常开心!它使用片刻进行解析和格式化。它看起来有点像前面提到的SunnyShah那样。

angular.module('app.directives')

.directive('appDatetime', function ($window) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            var moment = $window.moment;

            ngModel.$formatters.push(formatter);
            ngModel.$parsers.push(parser);

            element.on('change', function (e) {
                var element = e.target;
                element.value = formatter(ngModel.$modelValue);
            });

            function parser(value) {
                var m = moment(value);
                var valid = m.isValid();
                ngModel.$setValidity('datetime', valid);
                if (valid) return m.valueOf();
                else return value;
            }

            function formatter(value) {
                var m = moment(value);
                var valid = m.isValid();
                if (valid) return m.format("LLLL");
                else return value;

            }

        } //link
    };

}); //appDatetime

在我的表格中,我使用它:

<label>begin: <input type="text" ng-model="doc.begin" app-datetime required /></label>
<label>end: <input type="text" ng-model="doc.end" app-datetime required /></label>

这会将时间戳(自1970年以来的毫秒数)绑定到doc.begindoc.end

答案 6 :(得分:2)

我更喜欢服务器返回日期而不进行修改,并让javascript进行视图按摩。我的API返回&#34; MM / DD / YYYY hh:mm:ss&#34;来自SQL Server。

<强>资源

angular.module('myApp').factory('myResource',
    function($resource) {
        return $resource('api/myRestEndpoint/', null,
        {
            'GET': { method: 'GET' },
            'QUERY': { method: 'GET', isArray: true },
            'POST': { method: 'POST' },
            'PUT': { method: 'PUT' },
            'DELETE': { method: 'DELETE' }
        });
    }
);

<强>控制器

var getHttpJson = function () {
    return myResource.GET().$promise.then(
        function (response) {

            if (response.myDateExample) {
                response.myDateExample = $filter('date')(new Date(response.myDateExample), 'M/d/yyyy');
            };

            $scope.myModel= response;
        },
        function (response) {
            console.log(response.data);
        }
    );
};

myDate验证指令

angular.module('myApp').directive('myDate',
    function($window) {
        return {
            require: 'ngModel',
            link: function(scope, element, attrs, ngModel) {

                var moment = $window.moment;

                var acceptableFormats = ['M/D/YYYY', 'M-D-YYYY'];

                function isDate(value) {

                    var m = moment(value, acceptableFormats, true);

                    var isValid = m.isValid();

                    //console.log(value);
                    //console.log(isValid);

                    return isValid;

                };

                ngModel.$parsers.push(function(value) {

                    if (!value || value.length === 0) {
                         return value;
                    };

                    if (isDate(value)) {
                        ngModel.$setValidity('myDate', true);
                    } else {
                        ngModel.$setValidity('myDate', false);
                    }

                    return value;

                });

            }
        }
    }
);

<强> HTML

<div class="form-group">
    <label for="myDateExample">My Date Example</label>
    <input id="myDateExample"
           name="myDateExample"
           class="form-control"
           required=""
           my-date
           maxlength="50"
           ng-model="myModel.myDateExample"
           type="text" />
    <div ng-messages="myForm.myDateExample.$error" ng-if="myForm.$submitted || myForm.myDateExample.$touched" class="errors">
        <div ng-messages-include="template/validation/messages.html"></div>
    </div>
</div>

<强>模板/验证/ messages.html

<div ng-message="required">Required Field</div>
<div ng-message="number">Must be a number</div>
<div ng-message="email">Must be a valid email address</div>
<div ng-message="minlength">The data entered is too short</div>
<div ng-message="maxlength">The data entered is too long</div>
<div ng-message="myDate">Must be a valid date</div>

答案 7 :(得分:2)

在Angular2 +中感兴趣的人:

<input type="text" placeholder="My Date" [ngModel]="myDate | date: 'longDate'">

DatePipe Angular中的过滤器类型。

答案 8 :(得分:1)

Angularjs ui bootstrap 你可以使用angularjs ui bootstrap,它也提供日期验证

<input type="text"  class="form-control" 
datepicker-popup="{{format}}" ng-model="dt" is-open="opened" 
min-date="minDate" max-date="'2015-06-22'"  datepickeroptions="dateOptions"
date-disabled="disabled(date, mode)" ng-required="true"> 



在控制器中可以指定要将日期显示为datefilter的任何格式

   $ scope.formats = [&#39; dd-MMMM-yyyy&#39;,&#39; yyyy / MM / dd&#39;,&#39; dd.MM.yyyy&#39;,&#39; shortDate& #39];