AngularJS: wyłączanie wszystkich formantów formularza między przesłaniem a odpowiedzią serwera

122

Mam dylemat co do tego, jakie jest najlepsze (i poprawne) podejście, jeśli chcę wyłączyć kontrolki formularza (lub przynajmniej uczynić je niedostępnymi dla interakcji użytkownika) w czasie, gdy użytkownik kliknie przycisk „Zapisz” lub „Prześlij” i dane przesyłane przez kabel. Nie chcę używać JQuery (co jest złe !!!) i sprawdzać wszystkie elementy jako tablicę (według klasy lub znacznika atrybutu). Do tej pory miałem następujące pomysły:

  • Oznacz wszystkie elementy cm-form-controlniestandardową dyrektywą, która zaprenumeruje 2 powiadomienia: „data-sent” i „data-processing”. Następnie kod niestandardowy jest odpowiedzialny za przekazanie drugiego powiadomienia lub zrealizowanie obietnicy.
  • Użyj promiseTrackertych (niestety!) Wymuszeń, aby stworzyć wyjątkowo głupi kod, taki jak ng-show="loadingTracker.active()". Oczywiście nie wszystkie elementy mają ng-disabledi nie chcę, aby użytkownik ng-hide/showunikał „tańczących” przycisków.
  • Ugryź kulę i nadal używaj JQuery

Czy ktoś ma lepszy pomysł? Z góry dziękuję!

AKTUALIZACJA: Idea zestawu terenowego DZIAŁA. Oto proste skrzypce dla tych, którzy nadal chcą robić to samo 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>

i 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
źródło
z jakiej usługi korzystasz do przesyłania danych z formularza? $ http czy $ zasób?
François Romain
Właściwie to $ http, ponieważ nie muszę zajmować się niczym wyjątkowym.
YoMan78
Wyłączone zestawy pól nie działają w IE, czyli nie są rozwiązaniem. Używam modalu Bootstrap i ustawiam tło na statyczne.
im1dermike
Zauważ, że w czasie pisania pojawił się błąd, w którym fieldsetnie można go używać jako kontenera flexbox
George Mauer

Odpowiedzi:

283

Owinąć wszystkie pola w zestaw pól i używać ngDisabled dyrektywę tak:

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

Automatycznie wyłączy wszystkie wejścia wewnątrz zestawu pól.

Następnie w kontrolerze ustawiony $scope.isSavingna trueprzed wywołaniem http i na falsepóźniej.

Alexander Puchkov
źródło
Wygląda na to, że naprawdę działa dobrze nawet z <button>! Wielkie dzięki Sasha.
YoMan78
9
To dobra wskazówka, chociaż niestety atrybut disabled w zestawie
pól
5
@kiwiaddo W moich testach działa dobrze w IE9 +. Nawiasem mówiąc, w3schools.com nie jest najlepszą stroną referencyjną. Lepiej sprawdź tę stronę developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Alexander Puchkov
3
Przycisk typu wejścia, tekst i plik nie są wyłączone w IE11 :-(, również przycisk jest wyszarzony, ale kątowy moduł obsługi kliknięcia nadal działa.
Sebastian
3
@ im1dermike you right, to rzeczywiście nie działa w IE. Pole jest wizualnie oznaczone jako wyłączone, ale użytkownik może nadal wchodzić z nim w interakcję i edytować je tak, jakby było włączone. W IE jest błąd dla tego już przesłanego i został naprawiony, ale jeszcze nie wysłany. Będzie dostępny w następnym głównym wydaniu IE connect.microsoft.com/IE/feedbackdetail/view/962368/…
Alexander Puchkov
-5

W nowoczesnych przeglądarkach istnieje proste rozwiązanie:

  1. zdefiniuj klasę CSS

    .disabled {
      pointer-events: none;
      ... ...
    }
  2. dodaj tę klasę do ng-form

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

Tutaj jest wskaźnik-events wykres wsparcie.

Uwaga: nawet jeśli ustawisz pointer-events: none, nadal możesz użyć klawisza Tab, aby wprowadzić element za pomocą klawiatury.

Raoh
źródło