wake-up-neo.net

Verwenden des anglejs-Filters im Eingabeelement

Ich hoffe, ich habe nichts Offensichtliches im Doco übersehen, wenn ich sicher bin, dass jemand helfen wird.

Ich verwende asp.net webapi, um ein DTO mit Datumsfeldern zurückzugeben. Diese werden mit JSON.Net (im Format '2013-03-11T12: 37: 38.693') serialisiert. 

Ich möchte einen Filter verwenden, aber in einem INPUT-Element. Ist dies möglich, oder sollte ich einen neuen Filter oder eine neue Anweisung erstellen, um dies zu erreichen?

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

Gibt es eine Abkürzung, die mir fehlt?

73
leon

Kurz gesagt: Wenn Sie möchten, dass Ihre Daten in der Ansicht und im Modell eine andere Darstellung haben, benötigen Sie eine -Direktive, die Sie sich als Zwei-Wege-Filter vorstellen können.

Ihre Anweisung würde ungefähr so ​​aussehen

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" /> 

Hier ist ein funktionierendes jsFiddle - Beispiel.

131

Unterschiedliche Werte in Ihrem Eingabefeld und in Ihrem Modell widersprechen der Natur von ng-model. Ich schlage daher vor, dass Sie den einfachsten Ansatz wählen und Ihren Filter im Controller anwenden, indem Sie eine separate Variable für das formatierte Datum verwenden und Beobachter einsetzen, um formatierte und ursprüngliche Daten synchron zu halten:

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

Wenn Ihre Eingabe nur Daten anzeigt

Wenn Sie tatsächlich eine Eingabe benötigen, um einfach Anzeige einige Informationen einzugeben, und es ist ein anderes Element, das Änderungen das Angular-Modell enthält, können Sie eine einfachere Änderung vornehmen. 

Anstelle der neuen Direktive schreiben Sie einfach NICHT VERWENDEN den ng-model und verwenden Sie die gute, alte value.

Also statt:

<input data-ng-model={{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" /> 

Das wird es tun:

<input value="{{entity.date|date:'dd/MM/yyyy HH:mm:ss'}}" /> 

Und funktioniert wie ein Zauber :)

16
Atais

Vollständiges Beispiel, das Zahlen formatiert und ab dem Ende alle 3 Zeichen Leerzeichen einfügt:

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

Verwendungszweck:

<input ng-model="price" intersperse/>

Plunkr Beispiel: http://plnkr.co/edit/qo0h9z

3
Valentin

Angular verfügt über eine integrierte date-Format -Funktionalität. Wenn Sie diese Funktion jedoch auf eine Eingabe anwenden möchten, für die Sie das unformatierte (unformatierte) Datum erhalten möchten, müssen Sie eine benutzerdefinierte direktive erstellen.

Beispielrichtlinie:

(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;
                });
            }
        };
    }]);
})();

Dann um es anzuwenden:

<input type="text" ng-model="$ctrl.DateField" utc-date />
0
pistol-pete