AngularJS: Deaktivieren aller Formularsteuerelemente zwischen Senden und Serverantwort

122

Ich habe ein Dilemma darüber, was der beste (und richtige) Ansatz ist, wenn ich Formularsteuerelemente während eines Zeitraums, in dem der Benutzer auf die Schaltfläche "Speichern" oder "Senden" klickt, deaktivieren (oder zumindest für die Benutzerinteraktion nicht verfügbar machen) möchte und Daten, die über das Kabel übertragen werden. Ich möchte JQuery nicht verwenden (was böse ist !!!) und alle Elemente als Array abfragen (nach Klassen- oder Attributmarker). Die Ideen, die ich bisher hatte, sind:

  • Markieren Sie alle Elemente mit einer cm-form-controlbenutzerdefinierten Direktive, die zwei Benachrichtigungen abonniert: "Daten gesendet" und "Daten verarbeitet". Dann ist der benutzerdefinierte Code dafür verantwortlich, die zweite Benachrichtigung zu senden oder ein Versprechen zu lösen.
  • Verwenden Sie promiseTrackerdas (leider!) Erzwingt, um extrem dummen Code wie zu produzieren ng-show="loadingTracker.active()". Offensichtlich haben nicht alle Elemente ng-disabledund ich möchte nicht, dass Benutzer ng-hide/show"tanzende" Schaltflächen vermeiden.
  • Beißen Sie eine Kugel und verwenden Sie immer noch JQuery

Hat jemand eine bessere Idee? Danke im Voraus!

AKTUALISIERT: Die Fieldset-Idee funktioniert. Hier ist eine einfache Geige für diejenigen, die immer noch das Gleiche tun möchten: 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>

und 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
quelle
Mit welchem ​​Dienst senden Sie die Daten aus dem Formular? $ http oder $ resource?
François Romain
Es ist eigentlich $ http, da ich mich mit nichts Außergewöhnlichem befassen muss.
YoMan78
Deaktivierte Feldsätze funktionieren im IE nicht, dh keine Lösung. Ich benutze ein Bootstrap-Modal und setze den Hintergrund auf statisch.
im1dermike
Beachten Sie, dass zum Zeitpunkt des Schreibens gibt es einen Fehler , wenn fieldsetnicht als Flexbox Behälter verwendet werden kann
George Mauer

Antworten:

283

Wickeln Sie alle Ihre Felder in fieldset ein und verwenden Sie die Anweisung ngDisabled wie folgt :

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

Alle Eingaben im Feldset werden automatisch deaktiviert.

Dann im Controller $scope.isSavingauf truevor http-Aufruf und falsenach einstellen .

Alexander Puchkov
quelle
Scheint, als würde es sogar mit <Button> wirklich gut funktionieren! Vielen Dank Sasha.
YoMan78
9
Es ist ein guter Tipp, obwohl das deaktivierte Attribut für ein Feldset in IE oder Safari leider
kiwiaddo
5
@kiwiaddo Es funktioniert gut in IE9 + in meinen Tests. Übrigens ist w3schools.com nicht die beste Referenzwebsite. Überprüfen Sie besser diese Seite developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Alexander Puchkov
3
Eingabetyp-Schaltfläche, Text und Datei in IE11 nicht deaktiviert :-(, auch die Schaltfläche ist ausgegraut, aber der eckige ng-click-Handler wird weiterhin ausgelöst
Sebastian,
3
@ im1dermike du hast recht, es funktioniert in der Tat nicht im IE. Das Feld ist visuell als deaktiviert gestaltet, der Benutzer kann jedoch weiterhin mit ihm interagieren und es so bearbeiten, als ob es aktiviert wäre. Es gibt einen Fehler im IE für diesen bereits eingereichten und er wurde behoben, aber noch nicht ausgeliefert. Es wird in der nächsten IE-Hauptversion connect.microsoft.com/IE/feedbackdetail/view/962368/… verfügbar sein
Alexander Puchkov
-5

In modernen Browsern gibt es eine einfache Lösung:

  1. Definieren Sie eine CSS-Klasse

    .disabled {
      pointer-events: none;
      ... ...
    }
    
  2. füge diese Klasse hinzu ng-form

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

Hier ist die Zeiger-Ereignisse Unterstützung Chart.

Hinweis: Auch wenn Sie festlegen pointer-events: none, können Sie mit Ihrer Tastatur auf das Eingabeelement tippen.

Raoh
quelle