AngularJS: disabilitazione di tutti i controlli del modulo tra invio e risposta del server


122

Ho un dilemma su quale sia l'approccio migliore (e corretto) se desidero disabilitare i controlli del modulo (o almeno renderli non disponibili per l'interazione dell'utente) durante un periodo di tempo in cui l'utente fa clic sul pulsante "Salva" o "Invia" e dati che viaggiano sul filo. Non voglio usare JQuery (che è malvagio !!!) e interrogare tutti gli elementi come array (per classe o indicatore di attributo) Le idee che ho avuto finora sono:

  • Contrassegna tutti gli elementi con una cm-form-controldirettiva personalizzata che si abbonerà a 2 notifiche: "dati inviati" e "dati elaborati". Quindi il codice personalizzato è responsabile del push della seconda notifica o della risoluzione di una promessa.
  • Usa promiseTrackerche (sfortunatamente!) Impone di produrre codice estremamente stupido come ng-show="loadingTracker.active()". Ovviamente non tutti gli elementi hanno ng-disablede non voglio che l'utente ng-hide/showeviti i pulsanti "danzanti".
  • Morde un proiettile e usa ancora JQuery

Qualcuno ha un'idea migliore? Grazie in anticipo!

AGGIORNATO: l'idea del fieldset FUNZIONA. Ecco un semplice violino per coloro che vogliono ancora fare lo stesso 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);
    };
});

quale servizio stai utilizzando per inviare i dati dal form? $ http o $ risorsa?
François Romain

In realtà è $ http perché non ho bisogno di occuparmi di nulla di eccezionale.
YoMan78

I fieldset disabilitati non funzionano in IE, cioè non sono una soluzione. Uso un modale Bootstrap e imposto lo sfondo su statico.
im1dermike

Si noti che al momento della scrittura c'è un bug in cui fieldsetnon può essere usato come contenitore FlexBox
George Mauer

Risposte:


283

Avvolgi tutti i tuoi campi in fieldset e usa la direttiva ngDisabled in questo modo:

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

Disabiliterà automaticamente tutti gli input all'interno del fieldset.

Quindi nel controller impostato $scope.isSavingsu trueprima della chiamata http e su falsedopo.


Sembra che funzioni davvero bene anche con <button>! Grazie mille Sasha.
YoMan78

9
È un buon suggerimento, sebbene sfortunatamente l'attributo disabilitato su un fieldset non sia supportato in IE o Safari w3schools.com/tags/att_fieldset_disabled.asp
kiwiaddo

5
@kiwiaddo Funziona bene in IE9 + nei miei test. A proposito, w3schools.com non è il miglior sito web di riferimento. È meglio controllare questa pagina developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Alexander Puchkov

3
Pulsante del tipo di input, testo e file non disabilitati in IE11 :-(, anche il pulsante è disattivato ma il gestore di clic angolare si attiva ancora.
Sebastian,

3
@ im1dermike hai ragione, in effetti non funziona in IE. Il campo ha uno stile visivo disabilitato, ma l'utente può comunque interagire con esso e modificarlo come se fosse abilitato. C'è un bug in IE per questo già inviato ed è stato corretto, ma non ancora spedito. Sarà disponibile nella prossima major release di IE connect.microsoft.com/IE/feedbackdetail/view/962368/…
Alexander Puchkov

-5

C'è una soluzione semplice nei browser moderni:

  1. definire una classe CSS

    .disabled {
      pointer-events: none;
      ... ...
    }
    
  2. aggiungi questa classe a ng-form

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

Ecco latabella di supporto degli eventi del puntatore .

Nota: anche se si imposta pointer-events: none, è comunque possibile utilizzare la tabulazione per inserire l'elemento con la tastiera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.