2015-09-16 4 views
2

Мы пытаемся использовать momentjs для его функций часового пояса, которые являются удивительными. Мы также используем bootprap ui timepicker, который ожидает datetime как ng-model. Теперь попытка конвертировать момент в datetime теряет часовой пояс и переключается обратно в локальный часовой пояс. Я думал о том, чтобы создать собственный пользовательский таймер, но сначала я хотел проверить и посмотреть, не сталкивался ли кто-то еще с этой проблемой раньше. Заранее спасибо!Moment js Timepicker

(function() { 
'use strict'; 
moment.tz.setDefault("America/Phoenix"); 
angular.module('timepickerPop', ['ui.bootstrap']) 
.factory('timepickerState', function() { 
    var pickers = []; 
    return { 
     addPicker: function (picker) { 
      pickers.push(picker); 
     }, 
     closeAll: function() { 
      for (var i = 0; i < pickers.length; i++) { 
       pickers[i].close(); 
      } 
     } 
    }; 
}) 
.filter('momentFilter', function() { 
    return function (input) { 
     if (input == undefined) return ""; 
     return input.format("hh:mm A"); 
    }; 
}) 
.directive("timeFormat", ['$filter', function ($filter) { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     scope: { 
      showMeridian: '=', 
     }, 
     link: function (scope, element, attrs, ngModel) { 

      var parseTime = function (viewValue) { 

       //Not a concern at the moment 
      }; 

      ngModel.$parsers.push(parseTime); 

      var showTime = function (data) { 
       parseTime(data); 
       return $filter('momentFilter')(data); 
      }; 

      ngModel.$formatters.push(showTime); 

      scope.$watch('showMeridian', function (value) { 
       var myTime = ngModel.$modelValue; 
       if (myTime) { 
        element.val(showTime(myTime)); 
       } 

      }); 
     } 
    }; 
}]) 

.directive('timepickerPop', ['$document', 'timepickerState', function ($document, timepickerState) { 
    return { 
     restrict: 'E', 
     transclude: false, 
     scope: { 
      inputTime: "=", 
      showMeridian: "=", 
      disabled: "=" 
     }, 
     controller: ['$scope', '$element', function ($scope, $element) { 
      $scope.isOpen = false; 

      $scope.disabledInt = angular.isUndefined($scope.disabled) ? false : $scope.disabled; 

      $scope.toggle = function() { 
       if ($scope.isOpen) { 
        $scope.close(); 
       } else { 
        $scope.open(); 
       } 
      }; 
     }], 
     link: function (scope, element, attrs) { 
      var picker = { 
       open: function() { 
        timepickerState.closeAll(); 
        scope.isOpen = true; 
       }, 
       close: function() { 
        scope.isOpen = false; 
       } 

      } 
      timepickerState.addPicker(picker); 

      scope.open = picker.open; 
      scope.close = picker.close; 

      scope.$watch("disabled", function (value) { 
       scope.disabledInt = angular.isUndefined(scope.disabled) ? false : scope.disabled; 
      }); 

      scope.$watch("inputTime", function (value) { 
       if (!scope.inputTime) { 
        element.addClass('has-error'); 
       } else { 
        element.removeClass('has-error'); 
       } 

      }); 

      element.bind('click', function (event) { 
       event.preventDefault(); 
       event.stopPropagation(); 
      }); 

      $document.bind('click', function (event) { 
       scope.$apply(function() { 
        scope.isOpen = false; 
       }); 
      }); 
     }, 
     template: "<input type='text' class='form-control' ng-model='inputTime' ng-disabled='disabledInt' time-format show-meridian='showMeridian' ng-focus='open()' />" 
      + " <div class='input-group-btn' ng-class='{open:isOpen}'> " 
      + " <button type='button' ng-disabled='disabledInt' class='btn btn-default ' ng-class=\"{'btn-primary':isOpen}\" data-toggle='dropdown' ng-click='toggle()'> " 
      + "  <i class='glyphicon glyphicon-time'></i></button> " 
      + "   <div class='dropdown-menu pull-right'> " 
      + "   <timepicker ng-model='inputTime' show-meridian='showMeridian'></timepicker> " 
      + "   </div> " + " </div>" 
    }; 
}]); 

}());

+0

Что вы попробовали? покажите нам некоторый код, чтобы помочь –

ответ

0

То, что я делал в прошлом (вдохновленный бутстрапом ui date picker), использует другую директиву для того же элемента, в котором есть компилятор парсера/форматирования.

Что она делает это в основном переводить для начальной загрузки timpicker даты от moment объекта к Date одного и от Date обратно moment для конкретной модели.

Вот реализация для DatePicker:

.directive('uiDateMoment', [function() { 
    var directive = { 
     require: 'ngModel', 
     link: function (scope, element, attrs, modelCtrl) { 
      modelCtrl.$formatters.length = 0; 
      modelCtrl.$formatters.push(function (value) { 
       if (moment.isMoment(value)) { 
        var zoneDiffInMinutes = value.zone(); 
        var date = value.toDate(); 
        var tzDate = new Date(date.getTime() + (date.getTimezoneOffset() * 60000) - (zoneDiffInMinutes * 60000)); 
        return tzDate; 
       } 
       return null; 
      }); 
      modelCtrl.$parsers.push(function (value) { 
       if (value) { 
        var isoDate = moment(value).format('YYYY-MM-DD'); 
        return moment(isoDate + ' ' + (timeZoneOffset)).zone(timeZoneOffset); 
       } 
       return null; 
      }); 
     } 
    }; 
    return directive; 
}]); 

В моем случае timeZoneOffset глобальная переменная - которая не является идеальным, но вы можете двигаться, что к службе или что-то.

И он используется как:

<input type="text" ng-model="TargetDate" ui-date="UIDateSettings" ui-date-moment="mm/dd/yy" /> 

Вы можете, конечно, адаптировать это к timepicker тоже.

+0

Теперь у меня создалось впечатление, что $ formatter предназначен только для показа. – Samv12

Смежные вопросы