web-dev-qa-db-fra.com

Utilisation du filtre angularjs dans l'élément input

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?

73
leon

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 .

131

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

});
20
Stewie

Si votre entrée n'affiche que des données

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 :)

16
Atais

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

3
Valentin

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 />
0
pistol-pete