У меня есть вход, определенный как
<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>
он показывает, что, как Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time)
я предполагаю, JS отображает Date
объекты как строки.
Во-первых, как мне сказать Angular показывать дату в <input>
виде чего-то вроде 12/22/2009
? Кажется, я не могу применить |filters
внутри ng-model
атрибута.
Во-вторых, как только я редактирую дату, даже сохраняя ее в исходном формате, мой другой текст (внутри <td>
), похоже, больше не применяет |date
фильтр; он внезапно меняет форматы, чтобы соответствовать формату текстового поля ввода. Как заставить его применять |date
фильтр каждый раз при изменении модели?
Связанные вопросы:
Date()
функций js :$scope.departDate = new Date(); $scope.departTime = $scope.departDate.toTimeString().slice(0, 5);
и мне не нужны были другие фильтры или хитрые обходные пути в AngularJS IMO.Ответы:
Используйте настраиваемую проверку форм 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() : ""; }); } }; });
источник
var dateFormat = attrs.moMediumDate;
а неvar dateFormat = attrs.moDateInput;
moMediumDate, похоже, нигде не установлен, поэтому, если входы не создаются динамически, исходный формат никогда не выбирается.Вот очень удобная директива angular-datetime . Вы можете использовать это так:
<input type="text" datetime="yyyy-MM-dd HH:mm:ss" ng-model="myDate">
Он также добавляет маску к вашему вводу и выполняет проверку.
источник
datetime="<format>"
значении атрибута, соответствует формату, указанному в параметре DatepickerdateFormat
.Я создал простую директиву для включения стандартных
input[type="date"]
элементам формы правильно работать с AngularJS ~ 1.2.16.Смотри сюда: https://github.com/betsol/angular-input-date
А вот и демонстрация: http://jsfiddle.net/F2LcY/1/
источник
Я использую jquery datepicker для выбора даты. Моя директива считывает дату и конвертирует ее в формат даты json (в миллисекундах), хранится в
ng-model
данные при отображении отформатированной даты. И наоборот, если ng-модель имеет дату json (в миллисекундах), мой форматировщик отображается в моем формате как jquery datepicker.HTML-код:
<input type="text" jqdatepicker ng-model="course.launchDate" required readonly />
Угловая директива:
myModule.directive('jqdatepicker', function ($filter) { return { restrict: 'A', require: 'ngModel', link: function (scope, element, attrs, ngModelCtrl) { element.datepicker({ dateFormat: 'dd/mm/yy', onSelect: function (date) { var ar=date.split("/"); date=new Date(ar[2]+"-"+ar[1]+"-"+ar[0]); ngModelCtrl.$setViewValue(date.getTime()); scope.$apply(); } }); ngModelCtrl.$formatters.unshift(function(v) { return $filter('date')(v,'dd/MM/yyyy'); }); } }; });
источник
element.datepicker
сelement.pickadate
Поскольку вы использовали datepicker как класс, я предполагаю, что вы используете datepicker JQuery или что-то подобное.
Есть способ делать то, что вы намереваетесь, вообще без использования moment.js, используя только директивы datepicker и angularjs.
Я привел пример здесь, в этой скрипке
Выдержки из скрипки здесь:
Datepicker имеет другой формат, а формат angularjs отличается, необходимо найти соответствующее совпадение, чтобы дата была предварительно выбрана в элементе управления и также заполнялась в поле ввода, пока привязана ng-модель. Приведенный ниже формат эквивалентен
'mediumDate'
формату AngularJS.$(element).find(".datepicker") .datepicker({ dateFormat: 'M d, yy' });
Директива ввода даты должна иметь промежуточную строковую переменную для представления даты в удобочитаемой форме.
Обновление в разных разделах страницы должно происходить с помощью событий, таких как
$broadcast
и$on
.Использование фильтра для представления даты в удобочитаемой форме возможно и в ng-модели, но с временной переменной модели.
$scope.dateValString = $filter('date')($scope.dateVal, 'mediumDate');
источник
Я использую следующую директиву, которая делает меня и большинство пользователей очень счастливыми! Он использует момент для синтаксического анализа и форматирования. Он немного похож на упомянутый ранее 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.begin
иdoc.end
.источник
ngModel
находится ваш пользовательский идентификатор для аргумента контроллера, а не прямая именованная ссылка наngModel
. Это место, где соглашение об именовании этого аргумента «ctrl» или «контроллер» делает вещи более ясными и позволяет избежать путаницы.В Angular2 + для всех, кому интересно:
<input type="text" placeholder="My Date" [ngModel]="myDate | date: 'longDate'">
с типом фильтров в DatePipe Angular.
источник
Я предпочитаю, чтобы сервер возвращал дату без изменений, а javascript выполнял массирование представления. Мой API возвращает «ММ / ДД / ГГГГ чч: мм: сс» из 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>
источник
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 = ['dd-MMMM-yyyy', 'yyyy / MM / dd', 'dd.MM.yyyy', 'shortDate'];
источник