web-dev-qa-db-ja.com

入力要素でのangularjsフィルターの使用

もし誰かが助けてくれると確信していれば、ドコで明らかなことを見逃していないことを願っています。

Asp.net webapiを使用して、日付フィールドを含むDTOを返します。これらはJSON.Netを使用してシリアル化されます( '2013-03-11T12:37:38.693の形式)。

フィルターを使用したいのですが、INPUT要素でこれは可能ですか、またはこれを達成するために新しいフィルターまたはディレクティブを作成する必要がありますか?

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

不足しているショートカットはありますか?

73
leon

要するに、ビューとモデルでデータの表現を変えたい場合、directiveが必要です。 双方向フィルタとして。

あなたのディレクティブは次のようになります

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

動作する jsFiddle の例を次に示します。

131

入力フィールドとモデルで異なる値を使用すると、ng-modelの性質に反します。したがって、最も単純なアプローチを取り、コントローラー内にフィルターを適用し、フォーマットされた日付に別の変数を使用し、ウォッチャーを使用してフォーマットされた日付と元の日付を同期させることをお勧めします。

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

入力にデータのみが表示される場合

実際に単純な入力が必要な場合はdisplay情報であり、他の要素であるchanges Angularモデルを使用すると、簡単に変更できます。

新しいディレクティブを単に書く代わりに使用しないでください the ng-modelを使い、古くて良いvalueを使います。

代わりに:

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

これにより:

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

そして、魅力のように動作します:)

16
Atais

数字をフォーマットし、最後から3文字ごとにスペースを挿入する完全な例:

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

使用法:

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

Plunkrの例: http://plnkr.co/edit/qo0h9z

3
Valentin

Angularには date format 機能が組み込まれていますが、最終的に生の(フォーマットされていない)日付を取得したい入力に適用するには、カスタム 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;
                });
            }
        };
    }]);
})();

それを適用するには:

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