J'espère que rien dans le doco ne m'a échappé. Si j'y suis, je suis sûr que quelqu'un va m'aider.
J'utilise asp.net webapi pour renvoyer un DTO, avec des champs de date. Ceux-ci sont sérialisés à l'aide de JSON.Net (au format «2013-03-11T12: 37: 38.693»).
J'aimerais utiliser un filtre, mais dans un élément INPUT, est-ce possible ou dois-je créer un nouveau filtre ou une nouvelle directive pour accomplir cela?
// 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'}}
Y a-t-il un raccourci qui me manque?
En bref: si vous souhaitez que vos données aient une représentation différente dans la vue et dans le modèle, vous aurez besoin d'une directive, que vous pouvez considérer comme un filtre bidirectionnel .
Votre directive ressemblerait à quelque chose comme
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" />
Voici un exemple de travail jsFiddle .
Avoir des valeurs différentes dans votre champ de saisie et dans votre modèle va à l'encontre de la nature même de ng-model. Je vous suggère donc d'adopter l'approche la plus simple et d'appliquer votre filtre à l'intérieur du contrôleur, en utilisant une variable distincte pour la date formatée et en faisant appel à des observateurs pour synchroniser les dates formatées et les dates d'origine:
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'};
});
Si vous avez réellement besoin d’une entrée pour simplement afficher certaines informations et c’est un autre élément qui/ change le modèle angulaire, vous pouvez effectuer un changement plus facile.
Au lieu d'écrire une nouvelle directive, simplement NE PAS UTILISER le ng-model
et utilisez good, old value
.
Donc au lieu de:
<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
Cela fera:
<input value="{{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" />
Et fonctionne comme un charme :)
Exemple complet qui formate les nombres en insérant des espaces tous les 3 caractères, en partant de la fin:
'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, '')
Utilisation:
<input ng-model="price" intersperse/>
Exemple Plunkr: http://plnkr.co/edit/qo0h9z
Angular a construit dans format de date fonctionnalité, mais pour l’appliquer à une entrée où vous voudrez éventuellement obtenir la date brute (non formatée), vous devez créer une directive directive .
Exemple de directive:
(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;
});
}
};
}]);
})();
Puis pour l'appliquer:
<input type="text" ng-model="$ctrl.DateField" utc-date />