Come formattare una data usando ng-model?

Ho un input definito come

 

Che è truccato per essere visualizzato altrove nella pagina:

  Birth Date {{client.birthDate|date:'mediumDate'}}  

Quando la pagina carica la data di nascita è ben formattata come qualcosa come il Dec 22, 2009 . Tuttavia, quando guardo dentro il mio è mostrato come Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time) che immagino sia come JS esegue il rendering degli oggetti Date come stringhe.

Innanzitutto, come posso dire a Angular di mostrare la data in come qualcosa del 12/22/2009 ? Non riesco ad applicare i |filters all’interno dell’attributo ng-model .

In secondo luogo, non appena modifico la data, anche conservandola nel suo formato originale, il mio altro testo (all’interno di

) non sembra più applicare il filtro |date ; cambia improvvisamente i formati in modo che corrispondano a quelli della casella di testo di input. Come faccio ad applicare il filtro |date ogni volta che il modello cambia?


Domande correlate:

  • Come faccio a triggersre la mia direttiva solo su onchange?
  • Come accedere agli argomenti in una direttiva?

Usa la validazione personalizzata dei moduli http://docs.angularjs.org/guide/forms Demo: http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

Direttiva utilizzando formattatori e parser e 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() : ""; }); } }; }); 

Qui è molto utile la direttiva angular-datetime . Puoi usarlo in questo modo:

  

Aggiunge anche una maschera al tuo input ed esegue la validazione.

Ho creato una semplice direttiva per abilitare gli elementi di input[type="date"] standard input[type="date"] per funzionare correttamente con AngularJS ~ 1.2.16.

Guarda qui: https://github.com/betsol/angular-input-date

Ed ecco la demo: http://jsfiddle.net/F2LcY/1/

Sto usando jquery datepicker per selezionare la data. La mia direttiva legge la data e la converte in formato json data (in millisecondi) nei dati del ng-model mentre visualizza la data formattata. E inversa se ng-model ha una data json (in millisecondi) il mio formattatore viene visualizzato nel mio formato come jquery datepicker.

Codice html:

  

Direttiva angular:

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

Dato che hai usato datepicker come class, presumo che tu stia usando un datepicker o qualcosa di simile.

C’è un modo per fare ciò che si intende senza usare moment.js, usando solo le istruzioni datepicker e angularjs.

Ho dato un esempio qui in questo Fiddle

Estratti dal violino qui:

  1. Datepicker ha un formato diverso e il formato angularjs è diverso, è necessario trovare la corrispondenza appropriata in modo che la data sia preselezionata nel controllo e che venga anche popolata nel campo di input mentre il modello ng è associato. Il formato seguente è equivalente al formato 'mediumDate' di AngularJS.

     $(element).find(".datepicker") .datepicker({ dateFormat: 'M d, yy' }); 
  2. La direttiva di input della data deve avere una variabile di stringa temporanea per rappresentare la forma di data leggibile dall’uomo.

  3. L’aggiornamento su diverse sezioni della pagina dovrebbe avvenire tramite eventi, come $broadcast e $on .

  4. L’uso del filtro per rappresentare la data in forma leggibile dall’uomo è ansible anche nel modello ng ma con una variabile modello temporanea.

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

Io uso la seguente direttiva che rende me e la maggior parte degli utenti molto felici! Usa il momento per l’analisi e la formattazione. Sembra un po ‘come quello di SunnyShah, menzionato in precedenza.

 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 

Nella mia forma lo uso in questo modo:

   

Questo doc.begin un timestamp (millisecondi dal 1970) a doc.begin e doc.end .

Preferisco che il server restituisca la data senza modifiche e che javascript faccia massaggiare la vista. La mia API restituisce “MM / GG / AAAA hh: mm: ss” da SQL Server.

Risorsa

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

controllore

 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 Validation Directive

 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', 'MD-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

 

template / validazione / messages.html

 
Required Field
Must be a number
Must be a valid email address
The data entered is too short
The data entered is too long
Must be a valid date

In Angular2 + per chiunque sia interessato:

  

con tipo di filtri in DatePipe Angolare.

Angularjs ui bootstrap è ansible utilizzare angularjs ui bootstrap, fornisce anche la convalida della data

  

nel controller puoi specificare qualsiasi formato desideri visualizzare la data come datafilter

$ scope.formats = [‘dd-MMMM-yyyy’, ‘aaaa / MM / gg’, ‘gg.mm.aaaa’, ‘abbreviazione’];