1

編集 1:バグを修正しましたが、まだ機能していません。

element.val(ngModel.$viewValue || '');

になるはずだった:

dateInput.val(ngModel.$viewValue || '');

EDIT 2 :問題は、分離スコープが原因のようです。スコープがアイソレートの場合、注入されたngModel$render()メソッドが呼び出されません。スコープを非分離にして設定するとng-model="selectedDate"$render()期待どおりに呼び出されます。

EDIT 3:実際には問題は$parent.selectedDate. に変更するとselectedDate、コードは正常に機能しているようです。ただし、ディレクティブのスコープで定義されていないことを確認したいのですselectedDateが、親のスコープから継承されています。というわけで使いたいのですが$parent.、期待通りに動きません。


ブラウザーが HTML5 日付入力をサポートしている場合はそれを使用し、それ以外の場合は jQuery UI の日付ピッカーを使用するカスタム日付ピッカーを作成しています。これはまだ進行中の作業であり、現在はネイティブの HTML 5 日付入力を使用する部分のみが実装されています。

ディレクティブは次のように使用できます。

<div mil-datepicker ng-model="$parent.selectedDate"></div>

ただし、$scope.selectedDate初期値がある場合、ディレクティブによってレンダリングされません。また、selectedDate` への外部変更 (たとえば、ボタンをクリックすることによる) は、ディレクティブによって監視されていません。

私のコードで何が間違っている可能性がありますか?

コードのライブ バージョンは次のとおりです: milDatePicker

ディレクティブのコードは次のとおりです。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.selectedDate = '2020-01-01';
  $scope.changeDate = function() {
    $scope.selectedDate = '2030-03-03';
  };
});

app.directive('milDatepicker', function () {
   var template =
      '<div class="mil-datepicker clearfix">' +
         '   <input type="date" class="form-control">' +
         '   <div class="btn-group">' +
         '      <button type="button" class="btn btn-default btn-back">' +
         '         <span class="glyphicon glyphicon-chevron-left"></span>' +
         '      </button>' +
         '      <button type="button" class="btn btn-default btn-reset">Today</button>' +
         '      <button type="button" class="btn btn-default btn-forward">' +
         '         <span class="glyphicon glyphicon-chevron-right"></span>' +
         '      </button>' +
         '   </div>' +
         '</div>';

   return {
      template: template,
      restrict: 'A',
      require: 'ngModel',
      scope: {},
      priority: 0,
      link: function (scope, element, attrs, ngModel) {
         var nativeDatePickerHandlers = {
            back: function () {
               var $input = element.find("input").first();
               if ($input.val() === '' || $input.val() === undefined) {
                  return;
               }

               scope.$apply(function () {
                  var currentDate = moment($input.val(), "YYYY-MM-DD"),
                     yesterday = currentDate.subtract('days', 1).format("YYYY-MM-DD");

                  $input.val(yesterday);
                  ngModel.$setViewValue(yesterday);
               });
            },
            forward: function () {
               var $input = element.find("input").first();
               if ($input.val() === '' || $input.val() === undefined) {
                  return;
               }

               scope.$apply(function () {
                  var currentDate = moment($input.val(), "YYYY-MM-DD"),
                     tomorrow = currentDate.add('days', 1).format("YYYY-MM-DD");

                  $input.val(tomorrow);
                  ngModel.$setViewValue(tomorrow);
               });
            },
            reset: function () {
               var $input = element.find("input").first();

               scope.$apply(function() {
                  var today = moment().format("YYYY-MM-DD");
                  $input.val(today);
                  ngModel.$setViewValue(today);
               });
            },
            change: function () {
               var $this = $(this);

               scope.$apply(function () {
                  ngModel.$setViewValue($this.val());
               });
            }
         };

         function initNativeDatePicker(element) {
            var dateInput = element.find("input").first();

            element.find('.btn-back').first().on("click", nativeDatePickerHandlers.back);
            element.find('.btn-reset').first().on("click", nativeDatePickerHandlers.reset);
            element.find('.btn-forward').first().on("click", nativeDatePickerHandlers.forward);

            dateInput.on("change", nativeDatePickerHandlers.change);

            ngModel.$render = function () {
               dateInput.val(ngModel.$viewValue || '');
            };
         }

         // on browsers that support the HTML 5 date picker just use that
         // and do not use the jQuery UI DatePicker
         if (Modernizr.inputtypes.date) {
            initNativeDatePicker(element);
         } else {

         }
      }
   };
});
4

0 に答える 0