AngularJS: отключение всех элементов управления формой между отправкой и ответом сервера

122

У меня есть дилемма относительно того, какой подход является лучшим (и правильным), если я хочу отключить элементы управления формы (или, по крайней мере, сделать их недоступными для взаимодействия с пользователем) в течение периода времени, когда пользователь нажимает кнопку типа «Сохранить» или «Отправить». и данные, передаваемые по сети. Я не хочу использовать JQuery (что является злом !!!) и запрашивать все элементы как массив (по классу или маркеру атрибута). До сих пор у меня были следующие идеи:

  • Отметьте все элементы cm-form-controlспециальной директивой, которая будет подписываться на 2 уведомления: «данные отправлены» и «данные обработаны». Затем пользовательский код отвечает за отправку второго уведомления или выполнение обещания.
  • Используйте promiseTrackerэто (к сожалению!) Форсирование для создания чрезвычайно глупого кода вроде ng-show="loadingTracker.active()". Очевидно, что не все элементы есть, ng-disabledи я не хочу, чтобы пользователь ng-hide/showизбегал «танцующих» кнопок.
  • Укусите пулю и продолжайте использовать JQuery

Есть ли у кого-нибудь идея получше? Заранее спасибо!

ОБНОВЛЕНО: идея fieldset ДЕЙСТВИТЕЛЬНО работает. Вот простая скрипка для тех, кто все еще хочет сделать то же самое http://jsfiddle.net/YoMan78/pnQFQ/13/

HTML:

<div ng-app="myApp">
    <ng-form ng-controller="myCtrl">
        Saving: {{isSaving}}
        <fieldset ng-disabled="isSaving">
            <input type="text" ng-model="btnVal"/>
            <input type="button" ng-model="btnVal" value="{{btnVal}}"/>
            <button ng-click="save()">Save Me Maybe</button>
        </fieldset>
    </ng-form>
</div>

и JS:

var angModule = angular.module("myApp", []);

angModule.controller("myCtrl", function ($scope, $filter, $window, $timeout) {
    $scope.isSaving = undefined;
    $scope.btnVal = 'Yes';
    $scope.save = function()
    {
        $scope.isSaving = true;
        $timeout( function()
             {
                 $scope.isSaving = false;
                 alert( 'done');
             }, 10000);
    };
});
YoMan78
источник
какой сервис вы используете для отправки данных из формы? $ http или $ resource?
François Romain
На самом деле это $ http, так как мне не нужно иметь дело ни с чем выдающимся.
YoMan78
Отключенные наборы полей не работают в IE, т.е. не являются решением. Я использую модальное окно Bootstrap и устанавливаю статический фон.
im1dermike
Обратите внимание, что на момент написания есть ошибка, из-за которой fieldsetего нельзя использовать в качестве контейнера flexbox
Джордж Мауэр

Ответы:

283

Заверните все поля в FIELDSET и использовать ngDisabled директиву , как это:

<fieldset ng-disabled="isSaving"> ... inputs ...</fieldset>

Он автоматически отключит все входы внутри набора полей.

Затем в контроллере установлено $scope.isSavingзначение trueдо http-вызова и falseпосле.

Александр Пучков
источник
Похоже, он действительно отлично работает даже с <button>! Большое спасибо, Саша.
YoMan78
9
Это хороший совет, хотя, к сожалению, атрибут disabled в наборе
полей
5
@kiwiaddo В моих тестах он хорошо работает в IE9 +. Кстати, w3schools.com - не лучший справочный сайт. Лучше загляните на эту страницу developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Александр Пучков
3
Кнопка типа ввода, текст и файл не отключены в IE11 :-(, также кнопка неактивна, но угловой обработчик ng-click по-прежнему срабатывает.
Себастьян
3
@ im1dermike вы правы, это действительно не работает в IE. Поле визуально оформлено как отключенное, но пользователь все еще может взаимодействовать с ним и редактировать его, как если бы оно было включено. В IE есть ошибка, которая уже отправлена ​​и исправлена, но еще не отправлена. Он будет доступен в следующем основном выпуске IE connect.microsoft.com/IE/feedbackdetail/view/962368/…
Александр Пучков
-5

В современных браузерах есть простое решение:

  1. определить класс css

    .disabled {
      pointer-events: none;
      ... ...
    }
  2. добавить этот класс в ng-form

    <ng-form data-ng-class="{ 'disabled': isSaving }"> ... inputs ... </ng-form>

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

Примечание: даже если вы установили pointer-events: none, вы все равно можете использовать табуляцию для ввода элемента с клавиатуры.

Raoh
источник