Angular UI Bootstrap datepicker: поддержка ng-readonly

Angular UI Bootstrap datepicker не отличает атрибут ng-readonly. Если выражение ng-readonly истинно, поле ввода текста является серым и не может быть изменено, но всплывает календарь datepicker, позволяющий изменять поле формы.

До сих пор я пробовал 3 подхода (см. http://plnkr.co/edit/KHrbbI6W1pWG5ewSsE9r?p=preview), оба из которых довольно хаки и уродливы:

  • Отключение всех дат в datepicker, если оно должно быть только для чтения.

    <input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" date-disabled="disabled(date, mode)" />
    

    в html файле и

    $scope.$watch('ro', function(ro) {
      $scope.dt = new Date($scope.dt); // force datepicker div refresh
    });
    $scope.disabled = function(date, mode) {
      return $scope.ro;
    };
    

    в контроллере.

  • Нельзя всплывать всплывающее окно datepicker.

    <input type="text" datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" is-open="opened" />
    

    в html файле и

    $scope.$watch('opened', function(v1, v2, v3) {
      if ($scope.ro && v1) {
        $timeout(function() {
          $scope.opened = false;
        });
      }
    });
    

    в контроллере. Мигает datepicker выглядит ужасно.

  • Замена ввода текста датпикера с другим полем ввода только для чтения без привязки даты.

    <datepicker-ro-fix datepicker-popup="dd.MM.yyyy" ng-model="dt" ng-readonly="ro" />
    

    в html файле и

    m.directive('datepickerRoFix', function() {
      return {
        restrict: 'E',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          ngReadonly: '=',
        },
        template: '<span>'
          + '<input ng-hide="ngReadonly" type="text" datepicker-popup="dd.MM.yyyy" ng-model="ngModel" />'
          + '<input ng-show="ngReadonly" type="text" readonly="true" value="{{ ngModel | date:\'dd.MM.yyyy\'}}" />'
          + '</span>',
      };
    });
    

    в файле js. Пока это лучшее решение, но недостатком является то, что теперь есть два входных элемента вместо одного, оба имеют некоторые жестко заданные свойства.

Первый и второй подходы требуют от меня добавить кучу кода в контроллер формы для каждого поля ввода даты. Третий намного сложнее настроить.

Я новичок в angular и должен что-то упустить. Есть ли лучший способ сделать поля ввода с datepicker действительно доступными только для чтения?

Ответ 1

Ваш третий подход довольно приятный, imho.

Учитывая, что сам datepicker явно не поддерживает свойство readonly, я не вижу другого способа сделать его доступным только для чтения (и вы даже создали для него директиву)

Ваш второй подход иногда приводит к незначительному мерцанию при нажатии на вход (это только я?)

Что касается настройки, не могли бы вы объяснить, почему это трудно сделать? Думаю, вам нужно было бы передать все возможные атрибуты исходной директивы через вашу директиву?

Ответ 2

ng-disabled="true"

работал у меня. Angularjs: 1.2.9 и ui-boostrap: 0.8.0

К сожалению, у меня недостаточно репутации, чтобы прокомментировать исходный ответ

Ответ 3

Используйте ng-disabled="true"

<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="date" min="minDate" max="maxDate" ng-disabled="true" readonly="true"/>