AngularJS: vô hiệu hóa tất cả các điều khiển biểu mẫu giữa phản hồi gửi và máy chủ


122

Tôi có một tình huống khó xử về cách tiếp cận tốt nhất (và đúng) nếu tôi muốn tắt các điều khiển biểu mẫu (hoặc ít nhất là làm cho chúng không khả dụng cho người dùng tương tác) trong một khoảng thời gian khi người dùng nhấp vào nút "Lưu" hoặc "Gửi" và dữ liệu truyền qua dây. Tôi không muốn sử dụng JQuery (thật tệ hại !!!) và truy vấn tất cả các phần tử dưới dạng mảng (theo lớp hoặc điểm đánh dấu thuộc tính) Ý tưởng mà tôi có cho đến nay là:

  • Đánh dấu tất cả các phần tử bằng cm-form-controlchỉ thị tùy chỉnh sẽ đăng ký nhận 2 thông báo: "đã gửi dữ liệu" và "đã xử lý dữ liệu". Sau đó, mã tùy chỉnh chịu trách nhiệm đẩy thông báo thứ hai hoặc giải quyết một lời hứa.
  • Sử dụng promiseTrackerđiều đó (không may!) Thực thi để tạo ra mã cực kỳ ngu ngốc như ng-show="loadingTracker.active()". Rõ ràng là không phải tất cả các yếu tố đều có ng-disabledvà tôi không muốn người dùng ng-hide/showtránh các nút "nhảy múa".
  • Cắn một viên đạn và vẫn sử dụng JQuery

Có ai có một ý tưởng tốt hơn? Cảm ơn trước!

CẬP NHẬT: Ý tưởng tập trường KHÔNG hoạt động. Đây là một trò chơi đơn giản cho những ai vẫn muốn làm điều tương tự 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>

và 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);
    };
});

bạn đang sử dụng dịch vụ nào để gửi dữ liệu từ biểu mẫu? $ http hay $ tài nguyên?
François Romain

$ Http thực sự của nó vì tôi không cần phải xử lý bất cứ điều gì còn tồn đọng.
YoMan78

Các bộ trường bị vô hiệu hóa không hoạt động trong IE, tức là không phải là một giải pháp. Tôi sử dụng phương thức Bootstrap và đặt phông nền thành tĩnh.
im1dermike

Lưu ý rằng tại thời điểm viết bài có một lỗifieldsetkhông thể được sử dụng như một container flexbox
George Mauer

Câu trả lời:


283

Quấn trên mọi lĩnh vực của bạn trong fieldset và sử dụng ngDisabled chỉ thị như thế này:

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

Nó sẽ tự động vô hiệu hóa tất cả các đầu vào bên trong tập trường.

Sau đó, trong bộ điều khiển được đặt $scope.isSavingthành truetrước cuộc gọi http và falsesau đó.


Có vẻ như nó thực sự hoạt động tốt ngay cả với <button>! Cảm ơn rất nhiều Sasha.
YoMan78

9
Nó là một mẹo tốt, mặc dù tiếc là thuộc tính vô hiệu hóa trên một fieldset không được hỗ trợ trong IE hay Safari w3schools.com/tags/att_fieldset_disabled.asp
kiwiaddo

5
@kiwiaddo Nó hoạt động tốt trên IE9 + trong các thử nghiệm của tôi. Nhân tiện w3schools.com không phải là trang web tham khảo tốt nhất. Tốt hơn hãy kiểm tra trang này developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Alexander Puchkov 22/10/14

3
Nút loại đầu vào, văn bản và tập tin không bị vô hiệu hóa trong IE11 :-(, cũng nút chuyển sang màu xám nhưng góc ng nhấp chuột-handler vẫn cháy.
Sebastian

3
@ im1dermike bạn nói đúng, nó không hoạt động trên IE. Trường được tạo kiểu trực quan là bị vô hiệu hóa, nhưng người dùng vẫn có thể tương tác với nó và chỉnh sửa nó như thể nó đã được bật. Có một lỗi trong IE cho điều này đã được gửi và nó đã được sửa, nhưng vẫn chưa được vận chuyển. Nó sẽ có sẵn trong bản phát hành chính IE tiếp theo connect.microsoft.com/IE/feedbackdetail/view/962368/…
Alexander Puchkov

-5

Có một giải pháp đơn giản trong các trình duyệt hiện đại:

  1. xác định một lớp css

    .disabled {
      pointer-events: none;
      ... ...
    }
  2. thêm lớp này vào ng-form

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

Đây làbiểu đồ hỗ trợ con trỏ-sự kiện .

Lưu ý: ngay cả khi bạn đặt pointer-events: none, bạn vẫn có thể tab để nhập phần tử bằng bàn phím của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.