javascript - 画面 - AngularJs-入力フォーマットを変更するためのディレクティブ




qiita angularjs (2)

私は以下のことをやりたいのです。

私は自分のコントローラモデルにdateオブジェクトがあり、それをユーザに修正させたいのです。 ユーザーは2つの入力フィールドを与えられるべきです。 最初の入力フィールドは日付を、それ以外は修正する必要があります。 両方の入力フィールドは同じ日付モデルで機能します。

<input ng-model="model.date" date-format="YYYY-MM-DD">
<input ng-model="model.date" date-format="HH:mm:SS">

私はこの拘束力に関する文献を見つけられませんでした。 通常、ng-modelディレクティブは入力フィールドの値を扱います。 今度はこの値を自分のフォーマットで上書きしたいと思います。 また、ユーザーが入力を変更した場合は、変更内容を解析してdateオブジェクトに戻す必要があります。

vanilla jsでの日付操作はちょっと変わっているので、日付と文字列のフォーマットと解析にはmoment.jsを使いました。

私の現在のアプローチはこのようになります:

app.directive('dateFormat', function() {
    return {
        restrict: 'A',
        link: function(scope, el, at) {
            var format = at.dateFormat;
            scope.$watch(at.ngModel, function(date) {
                var result = moment(date).format(format);
                el.val(result);
            });
        }
    };
});

ただし、ブラウザで入力値を変更したいと思うとすぐにこれは壊れます。 私はいくつかのNaNを得ます:NaN ...

私の質問は:

  • これをどのようにモデル化できますか?
  • このアプローチは角度のある哲学に有効ですか、それとも私はここで奇妙なことをしていますか?
  • ng-modelとdate-formatディレクティブを一緒に使用できますか?
  • もっと簡単な方法はありますか?

フィルタはあなたが探しているものです。

//In your controller
$scope.modelDate = $filter('date')(dateToFormat, "YYYY-MM-DD");

//In your view
<input ng-model="modelDate" type="text">

そうは言っても、あなたがやろうとしていることはそれほど "オフ"ではありませんでした。ユーザーが入力に書き込むたびにフォーマットが壊れるからです。 ngModelを使用する必要があります。これはDirective(API)を扱う特別な方法を持ち、リンクプロセスの4番目の引数として直接参照することができます。

だからあなたのコードのためにそれはこのようなものになるでしょう:

return {
  require: 'ngModel',
  link: function(scope, element, attrs, ngModelController) {
    ngModelController.$parsers.push(function(data) {
      //View -> Model
      return data;
    });
    ngModelController.$formatters.push(function(data) {
      //Model -> View
      return $filter('date')(data, "YYYY-MM-DD");
    });
  }
}

詳細はhere


私は同じ問題を抱えていた、そしていくつかの研究とテストの後、私は以下の解決策を思いついた。 すべてのキーストロークの間ではなく、 'blur'で目的の書式設定と検証を実行します。 各ステップの情報についてはコメントタグを見てください。 日付の検証を実行するにはmoment.jsが必要になります。

myApp.directive('validDate', function ($filter, $window, $parse, $timeout) {
return {
    require: '?ngModel',
    restrict: 'A',
    compile: function () {
        var moment = $window.moment;
        var getter, setter;
        return function (scope, element, attrs, ngModel) {
            //Declaring the getter and setter
            getter = $parse(attrs.ngModel);
            setter = getter.assign;
            //Set the initial value to the View and the Model
            ngModel.$formatters.unshift(function (modelValue) {
                if (!modelValue) return "";
                var retVal = $filter('date')(modelValue, "MM/dd/yyyy");
                setter(scope, retVal);
                console.log('Set initial View/Model value from: ' + modelValue + ' to ' + retVal);
                return retVal;
            });

            // If the ngModel directive is used, then set the initial value and keep it in sync
            if (ngModel) {
                element.on('blur', function (event) {
                    var date = moment($filter('date')(element.val(), "MM/dd/yyyy"));
                    // if the date entered is a valid date then save the value
                    if (date && moment(element.val(), "MM/DD/YYYY").isValid() && date <= moment() && date >= moment("01/01/1900")) {
                        element.css('background', 'white');
                        element[0].value = $filter('date')(date.toDate(), "MM/dd/yyyy");
                        console.log('change value to ' + element.val());
                        var newValue = element.val();
                        scope.$apply(function () {
                            setter(scope, newValue);
                        });
                    } else { //show an error and clear the value
                        console.log('INCORRECT VALUE ENTERED');
                        element.css('background', 'pink');
                        element[0].value = "";
                        scope.$apply(function () {
                            setter(scope, '');
                        });
                    }
                });
             }
         };
      }
  }; });

また、ディレクティブはビューで次のように使用できます。

<input type="text" ng-model="member.BirthDate" required valid-date />






angularjs