AngularJS: ปิดใช้งานการควบคุมฟอร์มทั้งหมดระหว่างการส่งและการตอบกลับของเซิร์ฟเวอร์


122

ฉันรู้สึกกระอักกระอ่วนเกี่ยวกับวิธีที่ดีที่สุด (และถูกต้อง) หากฉันต้องการปิดการใช้งานการควบคุมแบบฟอร์ม (หรืออย่างน้อยก็ทำให้ไม่สามารถใช้งานได้สำหรับการโต้ตอบของผู้ใช้) ในช่วงเวลาหนึ่งที่ผู้ใช้คลิกปุ่ม "บันทึก" หรือ "ส่ง" และข้อมูลที่เดินทางผ่านสายไฟ ฉันไม่ต้องการใช้ JQuery (ซึ่งชั่วร้าย !!!) และค้นหาองค์ประกอบทั้งหมดเป็นอาร์เรย์ (ตามคลาสหรือเครื่องหมายแอตทริบิวต์) ความคิดที่ฉันมีจนถึงตอนนี้คือ:

  • ทำเครื่องหมายองค์ประกอบทั้งหมดด้วยcm-form-controlคำสั่งที่กำหนดเองซึ่งจะสมัครรับการแจ้งเตือน 2 รายการ: "ส่งข้อมูล" และ "ประมวลผลข้อมูล" จากนั้นรหัสที่กำหนดเองจะรับผิดชอบในการส่งการแจ้งเตือนครั้งที่สองหรือแก้ไขคำสัญญา
  • ใช้การpromiseTrackerบังคับ (โชคร้าย!) เพื่อสร้างรหัสที่โง่มากเช่นng-show="loadingTracker.active()". เห็นได้ชัดว่าองค์ประกอบบางอย่างไม่มีng-disabledและฉันไม่ต้องการให้ผู้ใช้ng-hide/showหลีกเลี่ยงปุ่ม "เต้นรำ"
  • กัดกระสุนแล้วยังใช้ JQuery

ใครมีความคิดที่ดีกว่านี้หรือไม่? ขอบคุณล่วงหน้า!

อัปเดต: แนวคิด fieldset ใช้งานได้จริง นี่คือซอง่ายๆสำหรับผู้ที่ยังต้องการทำเหมือนเดิม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>

และ 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);
    };
});

คุณใช้บริการใดในการส่งข้อมูลจากแบบฟอร์ม $ http หรือ $ resource?
François Romain

จริงๆแล้วมันคือ $ http เพราะฉันไม่จำเป็นต้องจัดการกับอะไรที่โดดเด่น
YoMan78

ชุดฟิลด์ที่ปิดใช้งานไม่ทำงานใน IE กล่าวคือไม่ใช่โซลูชัน ฉันใช้โมดอล Bootstrap และตั้งค่าฉากหลังเป็นแบบคงที่
im1dermike

โปรดทราบว่าในขณะที่เขียนมีข้อผิดพลาดที่fieldsetไม่สามารถใช้เป็นคอนเทนเนอร์ flexbox ได้
George Mauer

คำตอบ:


283

ตัดฟิลด์ทั้งหมดของคุณในfieldsetและใช้คำสั่งngDisabledดังนี้:

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

โดยอัตโนมัติจะปิดการใช้งานอินพุตทั้งหมดภายใน fieldset

จากนั้นในคอนโทรลเลอร์ตั้งค่า$scope.isSavingเป็นtrueก่อนการโทร http และfalseหลังจากนั้น


ดูเหมือนว่ามันจะใช้งานได้ดีแม้จะใช้ <button>! ขอบคุณมาก Sasha
YoMan78

9
เป็นเคล็ดลับที่ดีแม้ว่าแอตทริบิวต์ที่ปิดใช้งานบน fieldset ไม่ได้รับการสนับสนุนใน IE หรือ Safari w3schools.com/tags/att_fieldset_disabled.asp
kiwiaddo

5
@kiwiaddo มันทำงานได้ดีใน IE9 + ในการทดสอบของฉัน โดยวิธีการที่ w3schools.com ไม่ใช่เว็บไซต์อ้างอิงที่ดีที่สุด ตรวจสอบหน้านี้ดีกว่าdeveloper.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
Alexander Puchkov

3
ปุ่มประเภทอินพุตข้อความและไฟล์ไม่ได้ปิดใช้งานใน IE11 :-( ปุ่มยังเป็นสีเทา แต่ตัวจัดการการคลิกเชิงมุมยังคงทำงานอยู่
เซบาสเตียน

3
@ im1dermike คุณถูกต้องมันใช้ไม่ได้ใน IE แน่นอน ช่องนี้มีรูปแบบการมองเห็นเป็นปิดใช้งาน แต่ผู้ใช้ยังสามารถโต้ตอบและแก้ไขได้ราวกับว่าเปิดใช้งานอยู่ มีข้อบกพร่องใน IE สำหรับสิ่งนี้ที่ส่งไปแล้วและได้รับการแก้ไขแล้ว แต่ยังไม่ได้จัดส่ง จะพร้อมใช้งานใน IE รุ่นหลักต่อไปconnect.microsoft.com/IE/feedbackdetail/view/962368/…
Alexander Puchkov

-5

มีวิธีง่ายๆในเบราว์เซอร์สมัยใหม่:

  1. กำหนดคลาส css

    .disabled {
      pointer-events: none;
      ... ...
    }
    
  2. เพิ่มชั้นเรียนนี้ใน ng-form

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

นี่คือแผนภูมิการสนับสนุนตัวชี้เหตุการณ์

หมายเหตุ: แม้ว่าคุณจะตั้งค่าไว้pointer-events: noneคุณก็ยังสามารถแท็บเพื่อป้อนองค์ประกอบด้วยแป้นพิมพ์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.