AngularJS: desativando todos os controles de formulário entre o envio e a resposta do servidor


122

Eu tenho um dilema sobre qual é a melhor (e correta) abordagem se eu quiser desativar os controles de formulário (ou pelo menos torná-los indisponíveis para a interação do usuário) durante um período em que o usuário clica no botão "Salvar" ou "Enviar" e dados viajando pelo fio. Não quero usar o JQuery (o que é mau !!!) e consultar todos os elementos como array (por marcador de classe ou atributo). As idéias que tive até agora são:

  • Marque todos os elementos com a cm-form-controldiretiva personalizada, que assinará duas notificações: "dados enviados" e "dados processados". Em seguida, o código personalizado é responsável por enviar a segunda notificação ou resolver uma promessa.
  • Use promiseTrackerisso (infelizmente!) Impõe para produzir códigos extremamente estúpidos como ng-show="loadingTracker.active()". Obviamente, nem todos os elementos têm ng-disablede eu não quero que o usuário ng-hide/showevite "dançar" os botões.
  • Morda uma bala e ainda usa JQuery

Alguém tem uma idéia melhor? Desde já, obrigado!

ATUALIZADO: A idéia do fieldset funciona. Aqui está um violino simples para aqueles que ainda querem fazer o mesmo 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>

e 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);
    };
});

qual serviço você está usando para enviar os dados do formulário? $ http ou $ resource?
— François Romain

É realmente $ http como eu não preciso lidar com nada de excepcional.
— YoMan78

Os conjuntos de campos desativados não funcionam no IE, ou seja, não são uma solução. Eu uso um modal Bootstrap e defino o cenário como estático.
— im1dermike

Note-se que no momento da escrita não é um bug , onde fieldsetnão pode ser usado como um recipiente flexbox
— George Mauer

Respostas:


283

Coloque todos os seus campos no fieldset e use a diretiva ngDisabled da seguinte maneira:

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

Desabilitará automaticamente todas as entradas dentro do fieldset.

Em seguida, no controlador definido $scope.isSavingcomo trueantes da chamada http e falsedepois.


Parece que realmente funciona bem, mesmo com <button>! Muito obrigado Sasha.
— YoMan78

9
É uma boa dica, embora, infelizmente, o atributo disabled em um conjunto de campos não é suportado no IE ou Safari w3schools.com/tags/att_fieldset_disabled.asp
— kiwiaddo

5
@kiwiaddo Funciona bem no IE9 + nos meus testes. A propósito, o w3schools.com não é o melhor site de referência. Melhor verificar esta página developer.mozilla.org/pt-BR/docs/Web/HTML/Element/fieldset
— Alexander Puchkov

3
Botão tipo de entrada, texto e arquivos não desactivado no IE11 :-(, também botão é acinzentado, mas angular ng-click-manipulador ainda incêndios.
— Sebastian

3
@ im1dermike você está certo, ele realmente não funciona no IE. O campo possui estilo visual como desativado, mas o usuário ainda pode interagir com ele e editá-lo como se estivesse ativado. Há um bug no IE para isso já enviado e foi corrigido, mas ainda não foi enviado. Ele estará disponível na próxima versão principal do IE, connect.microsoft.com/IE/feedbackdetail/view/962368/…
— Alexander Puchkov 10/15

-5

Existe uma solução simples nos navegadores modernos:

  1. definir uma classe css

    .disabled {
      pointer-events: none;
      ... ...
    }
  2. adicione esta classe a ng-form

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

Aqui está ográfico de suporte a eventos de ponteiro .

Nota: mesmo se você definir pointer-events: none, ainda poderá tabular para inserir o elemento com o teclado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.