En utilisant AngularJS, je tente d’afficher une date à l’aide d’une entrée type=date
:
<input ng-model="campaign.date_start" type="date">
Cependant, cela donne l'erreur suivante:
Error: error:datefmt
Model is not a date object
La date provient en fait d'une API JSON au format suivant:
date_start": "2014-11-19"
J'ai pensé que je pouvais le résoudre en utilisant un filtre, mais cela n'a pas fonctionné et j'obtiens la même erreur avec:
<input ng-model="campaign.date_start | date" type="date">
J'ai aussi essayé de convertir la chaîne en une date, mais j'obtiens encore la même erreur:
$scope.campaign.date_start = Date(campaign.date_start);
Que puis-je essayer?
Vous devez instancier campaign.date_start
avec Date
pour ne pas l'utiliser comme une fonction.
Cela devrait ressembler à quelque chose comme ça (petite démo):
$scope.campaign.date_start = new Date(campaign.date_start);
Vous pouvez utiliser cette directive.
angular.module('app')
.directive("formatDate", function(){
return {
require: 'ngModel',
link: function(scope, elem, attr, modelCtrl) {
modelCtrl.$formatters.Push(function(modelValue){
return new Date(modelValue);
})
}
}
})
Dans votre html;
<input type="date" ng-model="date" format-date>
$formatters
Array.<Function>
Tableau de fonctions à exécuter, en tant que pipeline, chaque fois que la valeur du modèle change. Les fonctions sont appelées dans l'ordre inverse, chacune transmettant la valeur à la suivante. La dernière valeur renvoyée est utilisée comme valeur DOM actuelle. Utilisé pour formater/convertir les valeurs à afficher dans le contrôle.
La directive de cs1707
est excellente, sauf si la valeur de la portée de la date est null
ou undefined
, elle initialisera une date avec 1/1/1970
. Ce n'est probablement pas optimal pour la plupart des gens
Ci-dessous, une version modifiée de la directive cs1707
qui laissera un modèle null
/undefined
tel quel:
angular.module('app').directive("formatDate", function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, modelCtrl) {
modelCtrl.$formatters.Push(function(modelValue) {
if (modelValue){
return new Date(modelValue);
}
else {
return null;
}
});
}
};
});
Dans votre html;
<input type="date" ng-model="date" format-date>
Une autre option
Si vous souhaitez que cela s'applique à toutes les entrées de type date, il n'est pas nécessaire d'ajouter l'attribut format-date à chaque élément d'entrée. Vous pouvez utiliser la directive suivante. (Soyez prudent avec cela, car il pourrait interagir avec d'autres directives personnalisées de manière inattendue.)
angular.module('app').directive("input", function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, modelCtrl) {
if (attr['type'] === 'date'){
modelCtrl.$formatters.Push(function(modelValue) {
if (modelValue){
return new Date(modelValue);
}
else {
return null;
}
});
}
}
};
});
Dans votre html;
<input type="date" ng-model="date">
Une autre solution directive ici:
//inside directives.js
.directive('dateField', function () {
return {
restrict: ' E',
scope: {
ngBind: '=ngModel',
ngLabel: '@'
},
replace: true,
require: 'ngModel',
controller: function ($scope) {
if ($scope.ngBind != null) {
var pattern = /Date\(([^)]+)\)/;
var results = pattern.exec($scope.ngBind);
var dt = new Date(parseFloat(results[1]));
$scope.ngBind = dt;
};
},
templateUrl: 'templates/directives/dateField.html'
}
})
;
Ajoutez un modèle de directive comme ceci:
<!-- app.directives templates/directives/dateField -->
<script id="templates/directives/dateField.html" type="text/ng-template">
<label class="item item-input item-stacked-label ">
<span class="input-label">{{ngLabel}}</span>
<input type="date" placeholder="" ng-model="ngBind" />
</label>
</script>
Et l'utiliser
<date-field ng-label="This date..." ng-model="datajson.do.date"></date-field>
Bonne chance!
Utilisation de la directive pour réinitialiser les formateurs/analyseurs angulaires par défaut de ngModelCtrl.$formatters.length = 0; ngModelCtrl.$parsers.length = 0;
Cela fonctionne pour input[type="date"]
ainsi que input[type="time"]
. Fonctionne également bien pour l'application Cordova
HTML:
<input date-input type="time" ng-model="created_time">
Directive angulaire:
app.directive('dateInput', function () {
return {
require: 'ngModel',
link: function (scope, element, attr, ngModelCtrl) {
//Angular 1.3 insert a formater that force to set model to date object, otherwise throw exception.
//Reset default angular formatters/parsers
ngModelCtrl.$formatters.length = 0;
ngModelCtrl.$parsers.length = 0;
}
};
});
Une autre manière simple en utilisant une directive:
HTML:
<input date-input type="time" ng-model="created_time">
Directif:
app.directive('dateInput', function(){
return {
restrict : 'A',
scope : {
ngModel : '='
},
link: function (scope) {
if (scope.ngModel) scope.ngModel = new Date(scope.ngModel);
}
}
});
Vous pouvez éviter cette erreur en utilisant cette partie de code qui est en fait une erreur de format de date pendant que nous passons notre date à une fonction ou à une API.
var options = {
weekday: "long", year: "numeric", month: "short",
day: "numeric", hour: "2-digit", minute: "2-digit"
};
$scope.campaign.date_start = $scope.campaign.date_start.toLocaleTimeString("en-us", options);
où en-us format = vendredi 1 février 2013 06h00 J'espère que cela aidera les autres à résoudre le problème, je faisais face à une telle erreur et je le résolus avec cela.