ng-submit ใน AngularJS: การจัดการการส่งแบบฟอร์มพร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

ng-submit ใน AngularJS จะผูกฟังก์ชันของคอนโทรลเลอร์เข้ากับเหตุการณ์ submit ของฟอร์มในเบราว์เซอร์ ทำให้ค่าที่ป้อนเข้ามาได้รับการประมวลผลภายในคอนโทรลเลอร์ และหน้าเว็บจะไม่โหลดซ้ำผ่านการส่งแบบ POST ตามค่าเริ่มต้น

  • 🔘 บทบาทเชิงสั่งการ: ng-submit ผูกนิพจน์ AngularJS เข้ากับเหตุการณ์ submit ขององค์ประกอบฟอร์ม
  • ☑️ ไม่ต้องโหลดหน้าเว็บใหม่: โดยปกติแล้ว เบราว์เซอร์จะปิดใช้งานการส่งข้อมูลแบบ POST เว้นแต่ว่าแบบฟอร์มจะมีแอตทริบิวต์ action อยู่
  • ตัวอย่างการทำงาน: การใช้ textbox ร่วมกับ Display() จะเพิ่มแต่ละหัวข้อลงในอาร์เรย์ AllTopic สำหรับ ng-repeat
  • 🧪 ด่านตรวจสอบความถูกต้อง: การจับคู่ $valid กับ novalidate และ ng-disabled จะบล็อกการส่งข้อมูลที่ไม่สมบูรณ์
  • 🛠️ ข้อผิดพลาดทั่วไป: การผูก ng-click กับปุ่มส่งข้อมูลที่อยู่ข้างๆ ng-submit จะทำให้เกิดการส่งข้อมูลซ้ำซ้อน
  • 📊 หมายเหตุเกี่ยวกับเวอร์ชัน: การสนับสนุน AngularJS สิ้นสุดลงในเดือนมกราคม 2022; Angular รุ่นใหม่จะส่งคำขอผ่านทาง (ngSubmit)

คำสั่ง `ng-submit` ใน AngularJS ใช้สำหรับผูกเหตุการณ์การส่งฟอร์มเข้ากับฟังก์ชันในคอนโทรลเลอร์

สั่งส่ง AngularJS ng

การขอ ng-ส่ง คำสั่งใน AngularJS ใช้เพื่อผูกแอปพลิเคชันกับเหตุการณ์การส่งของเบราว์เซอร์ ดังนั้นในกรณีของ AngularJS ในเหตุการณ์การส่ง คุณสามารถดำเนินการประมวลผลบางอย่างภายในตัวควบคุมได้ จากนั้นจึงแสดงข้อมูลที่ประมวลผลแก่ผู้ใช้

หมายเหตุเกี่ยวกับเวอร์ชัน: AngularJS 1.x สิ้นสุดการสนับสนุนระยะยาว (Long Term Support) เมื่อวันที่ 31 ธันวาคม 2021 และทีมผู้พัฒนาเฟรมเวิร์กได้ยืนยันเรื่องนี้แล้ว การสนับสนุน AngularJS สิ้นสุดลงอย่างเป็นทางการแล้ว ในเดือนมกราคม 2022 ดังนั้นจึงไม่มีการอัปเดตหรือแพตช์ความปลอดภัยใดๆ ตามมา ทุกขั้นตอนและบล็อกโค้ดด้านล่างจะถูกเก็บรักษาไว้ตามที่เขียนไว้ทุกประการ เพื่อเป็นข้อมูลอ้างอิงทางประวัติศาสตร์ งานใหม่จะอยู่ใน Angular เวอร์ชันใหม่ ซึ่งแสดงแนวคิดเดียวกันกับเวอร์ชันก่อนหน้า (ngSubmit) ผูกกับ FormGroup.

วิธีส่งแบบฟอร์มใน AngularJS โดยใช้ ng-submit

โดยปกติกระบวนการส่งข้อมูลบนเว็บเพจจะได้รับการจัดการโดยเหตุการณ์การส่งบนเว็บเบราว์เซอร์ โดยปกติเหตุการณ์นี้ใช้เพื่อส่งข้อมูลที่ผู้ใช้อาจป้อนบนหน้าเว็บไปยังเซิร์ฟเวอร์เพื่อการประมวลผลเพิ่มเติม เช่น ข้อมูลการเข้าสู่ระบบ ข้อมูลแบบฟอร์ม ฯลฯ การส่งข้อมูลสามารถทำได้ผ่านคำขอ GET หรือ POST

มาดูตัวอย่างการส่งแบบฟอร์มเชิงมุมเพื่อดูวิธีการส่งแบบฟอร์มใน AngularJS

ในตัวอย่างการส่งแบบฟอร์ม AngularJS ของเรา เราจะนำเสนอกล่องข้อความให้ผู้ใช้ป้อนหัวข้อที่ต้องการเรียนรู้ จะมีปุ่มส่งอยู่ในหน้า เมื่อกดแล้ว หัวข้อนั้นจะเพิ่มลงในรายการแบบไม่เรียงลำดับ

ภาพประกอบด้านล่าง tracกระบวนการที่ไหลลื่น ตั้งแต่หัวข้อที่พิมพ์ลงในช่องข้อความ ผ่านปุ่มส่ง ไปจนถึงรายการที่เพิ่มเข้ามาด้านล่าง

ฟอร์ม AngularJS ที่ประกอบด้วยช่องข้อความสำหรับหัวข้อ ปุ่มส่ง และรายการหัวข้อที่ไม่เรียงลำดับที่ได้จากฟอร์ม
การส่งแบบฟอร์มใน AngularJS โดยใช้ ng-submit

ตัวอย่างการส่งแบบฟอร์ม AngularJS

ตอนนี้เราจะเห็นตัวอย่างของการส่งแบบฟอร์ม AngularJS จาก Controller โดยใช้คำสั่ง ng-submit:

<!DOCTYPE html>
<html>
<head>

    <meta chrset="UTF 8">
    <title>Event Registration</title>
</head>

<body  ng-app="sampleApp">
<script src="https://code.angularjs.org/1.6.9/angular-route.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<script src="lib/bootstrap.js"></script>
<script src="lib/bootstrap.css"></script>
<h1> Guru99 Global Event</h1>
<div ng-controller="AngularController">

    <form ng-submit="Display()">
        &nbsp;&nbsp;&nbsp;
        Enter which topic you would like to learn
        <input type="text"  ng-app="sampleApp" ng-model="Topic"><br>

        <input type="submit" value="Submit"/>

        <ul ng-repeat="topicname in AllTopic">
            <li>{{topicname}}</li>
        </ul>
    </form>
</div>

<script>
   var sampleApp = angular.module("sampleApp",[]);

    sampleApp.controller("AngularController",function($scope) {
        $scope.AllTopic=[];
        $scope.Display = function () {
            $scope.AllTopic.push($scope.Topic);
        }
    });
</script>
</body>
</html>

Code คำอธิบาย:

  1. ขั้นแรก เราจะประกาศแท็ก HTML สำหรับฟอร์ม ซึ่งจะบรรจุ "ช่องข้อความ" และ "ปุ่มส่ง" ดังแสดงในตัวอย่างการส่งฟอร์มของ Angular จากนั้น เราจะใช้คำสั่ง ng-submit ของ AngularJS เพื่อผูกฟังก์ชัน "Display()" เข้ากับฟอร์ม ฟังก์ชันนี้จะถูกกำหนดไว้ในคอนโทรลเลอร์และจะถูกเรียกเมื่อฟอร์มถูกส่ง
  2. เรามีการควบคุมข้อความที่ผู้ใช้จะเข้าสู่หัวข้อที่พวกเขาต้องการเรียนรู้ สิ่งนี้จะถูกผูกไว้กับตัวแปรที่เรียกว่า 'หัวข้อ' ซึ่งจะใช้ในคอนโทรลเลอร์ของเรา
  3. มีปุ่มส่งปกติใน AngularJS ซึ่งผู้ใช้จะคลิกเมื่อเข้าสู่หัวข้อที่ต้องการ
  4. เราใช้ ng-ซ้ำ คำสั่งเพื่อแสดงรายการของหัวข้อที่ผู้ใช้ป้อน คำสั่ง ng-repeat จะผ่านแต่ละหัวข้อในอาร์เรย์ 'AllTopic' และแสดงชื่อหัวข้อตามลำดับ
  5. ในคอนโทรลเลอร์ของเรา เราประกาศตัวแปรอาร์เรย์ชื่อ 'AllTopic' ซึ่งจะใช้สำหรับเก็บหัวข้อทั้งหมดที่ผู้ใช้ป้อนในขั้นตอนที่ 2
  6. เรากำลังกำหนดโค้ดสำหรับฟังก์ชัน Display() ของเรา ซึ่งจะถูกเรียกเมื่อใดก็ตามที่ผู้ใช้คลิกปุ่มส่ง ตรงนี้ เราใช้ฟังก์ชันพุชอาเรย์เพื่อเพิ่มหัวข้อที่ผู้ใช้ป้อนผ่านตัวแปร 'หัวข้อ' ลงในอาร์เรย์ 'AllTopic' ของเรา

หากดำเนินการโค้ดตัวอย่างแบบฟอร์ม AngularJS สำเร็จ ผลลัพธ์ต่อไปนี้จะปรากฏขึ้นเมื่อคุณรันโค้ดในเบราว์เซอร์
Output:

การแสดงผลในเบราว์เซอร์ของตัวอย่าง AngularJS ng-submit ที่แสดงช่องข้อความหัวข้อว่างเปล่าและปุ่มส่ง

หากต้องการดูการทำงานของโค้ด ขั้นแรกให้ป้อนชื่อหัวข้อ เช่น “Angular” ตามที่แสดงด้านบนในกล่องข้อความ จากนั้นคลิกที่ปุ่มส่ง

ผลลัพธ์จากคำสั่ง ng-submit ของ AngularJS หลังจากคลิกปุ่ม Submit โดยหัวข้อที่ป้อนจะถูกเพิ่มเข้าไปในรายการ

  • หลังจากที่คลิกปุ่มส่ง คุณจะเห็นรายการที่ป้อนในกล่องข้อความถูกเพิ่มไปยังรายการรายการ
  • สิ่งนี้สามารถทำได้โดยฟังก์ชัน Display() ซึ่งถูกเรียกเมื่อกดปุ่มส่ง
  • ฟังก์ชัน Display() จะเพิ่มข้อความลงในตัวแปรอาร์เรย์ที่เรียกว่า 'AllTopic' และคำสั่ง ng-repeat ของเราจะผ่านแต่ละค่าในตัวแปรอาร์เรย์ 'AllTopic' และแสดงเป็นรายการตามลำดับ

ng-submit vs ng-click: อันไหนที่จะใช้

ทั้งสอง ไดเร็กทีฟของ AngularJS สามารถเรียกใช้ฟังก์ชันควบคุมเดียวกันได้ แต่ฟังก์ชันเหล่านั้นรับฟังเหตุการณ์จากเบราว์เซอร์ที่แตกต่างกัน ng-submit อยู่บน <form> แท็กนี้ตอบสนองต่อเหตุการณ์การส่งข้อมูล ดังนั้นจึงทำงานเมื่อผู้ใช้กดปุ่ม Enter ภายในช่องกรอกข้อมูลด้วย ng-click ทำงานบนปุ่มและตอบสนองเฉพาะต่อการคลิกเมาส์หรือการเปิดใช้งานที่เทียบเท่าเท่านั้น

แง่มุม ng-ส่ง ng-คลิก
องค์ประกอบโฮสต์ แท็กแบบฟอร์ม องค์ประกอบใดๆ ที่สามารถคลิกได้
กิจกรรมที่รับฟัง กดส่งพร้อมกดปุ่ม Enter คลิกเท่านั้น
เบราว์เซอร์เริ่มต้น POST ถูกระงับโดยคำสั่ง ยังคงทำงานได้จากการกดปุ่มส่ง
การเข้าถึงสถานะแบบฟอร์ม อ่านค่า $valid และ $invalid จากตัวควบคุมฟอร์ม ไม่มีรูปแบบบริบทของตัวเอง
พอดีตัวเป็นธรรมชาติ ส่งข้อมูลฟอร์มไปยังตัวควบคุม ปุ่มแถบเครื่องมือ ลิงก์ ตัวกระตุ้นโมดอล

การรองรับแป้นพิมพ์มักจะเป็นตัวตัดสินใจ แบบฟอร์มที่เชื่อมต่อด้วย ng-click เบราว์เซอร์นี้ไม่สนใจปุ่ม Enter ซึ่งทำให้ผู้ใช้รู้สึกหงุดหงิดขณะกรอกข้อมูลล็อกอิน (สำรอง) ng-click สำหรับการกระทำที่ไม่ใช่การส่งแบบฟอร์ม เช่น การล้างข้อมูลในช่อง หรือการเปิดกล่องโต้ตอบ

เหตุใด ng-submit จึงป้องกันการส่งข้อมูลตามค่าเริ่มต้นของเบราว์เซอร์

แบบฟอร์ม HTML ธรรมดาจะตอบสนองต่อเหตุการณ์การส่งข้อมูลโดยการแปลงฟิลด์ต่างๆ เป็นรูปแบบอนุกรมและขอให้เบราว์เซอร์โหลดหน้าเว็บใหม่ ซึ่งจะทิ้งค่าทั้งหมดที่เก็บไว้ในฟิลด์เหล่านั้น $scopeส่วน ng-submit คำสั่งดังกล่าวจะหยุดยั้งไม่ให้สิ่งนั้นเกิดขึ้น: มันจะเรียก preventDefault() สำหรับคุณ ดังนั้นนิพจน์จึงทำงานและหน้าปัจจุบันยังคงอยู่ที่เดิม ไม่ $event ไม่จำเป็นต้องมีอาร์กิวเมนต์ และไม่ต้องเรียกใช้ฟังก์ชันด้วยตนเอง

การระงับมีเงื่อนไขที่ระบุไว้หนึ่งข้อ ตามข้อมูลของ ข้อมูลอ้างอิง ngSubmitการกระทำเริ่มต้นจะถูกป้องกันเฉพาะเมื่อแบบฟอร์มไม่มีข้อมูลใดๆ action, data-action or x-action แอตทริบิวต์ การเพิ่มแอตทริบิวต์ใดๆ เหล่านั้นจะทำให้เบราว์เซอร์นำทางไปตามปกติหลังจากตัวจัดการทำงานเสร็จสิ้น ซึ่งเป็นพฤติกรรมที่ถูกต้องสำหรับฟอร์มที่แสดงผลบนเซิร์ฟเวอร์แบบ Progressive Enhanced และเป็นเรื่องที่น่าประหลาดใจในกรณีอื่นๆ

เนื่องจากคำสั่งดังกล่าวจะกลืนกินอ็อบเจ็กต์เหตุการณ์ จึงต้องอ่านค่าที่ส่งมาจากคุณสมบัติที่ ng-รุ่น เขียนลงในขอบเขต หรือส่งผ่านอย่างชัดเจน เช่น ng-submit="Display(Topic)".

วิธีตรวจสอบความถูกต้องของแบบฟอร์มก่อนที่คำสั่ง ng-submit จะทำงาน

ตัวอย่างข้างต้นยอมรับหัวข้อว่างเปล่า เนื่องจากไม่มีการตรวจสอบช่องข้อความก่อน AngularJS สร้างตัวควบคุมฟอร์มสำหรับทุกฟอร์มที่มีชื่อ และตัวควบคุมนั้นจะแสดงแฟล็กที่จำเป็นในการควบคุมการส่งข้อมูล เพิ่ม novalidate ดังนั้นเบราว์เซอร์จึงปิดใช้งาน HTML5 bubbles ของตัวเอง และ AngularJS ก็เช่นกัน การตรวจสอบแบบฟอร์ม จะใช้เวลามากกว่า.

  1. ให้แบบฟอร์ม nameAngularJS จะเผยแพร่คอนโทรลเลอร์ที่มีชื่อนั้นไปยังพื้นที่โดยรอบ ตัวควบคุม ขอบเขต.
  2. เพิ่ม novalidate เพิ่มแท็ก <form> เข้าไป เพื่อไม่ให้ระบบตรวจสอบความถูกต้องของเบราว์เซอร์เข้ามาแทรกแซง
  3. ทำเครื่องหมายในช่องโดยใช้ required, ng-minlength, ng-maxlength or ng-pattern.
  4. คอยปกป้องผู้ดูแลด้วย $validและส่งตัวควบคุมฟอร์มเข้าไปเพื่อให้ฟังก์ชันสามารถตรวจสอบแต่ละฟิลด์ได้
  5. ปิดใช้งานปุ่มด้วย ng-disabled ชี้ไปที่ $invalidซึ่งให้ผลตอบรับทางสายตาในทันที
<form name="topicForm" ng-submit="topicForm.$valid && Display(topicForm)" novalidate>
    <input type="text" name="Topic" ng-model="Topic" required>
    <input type="submit" value="Submit" ng-disabled="topicForm.$invalid">
</form>

ข้อผิดพลาดสองประการนี้เป็นสาเหตุหลักของปัญหาที่พบได้บ่อยที่สุดเกี่ยวกับรูปแบบนี้:

  • Double ส่ง ผูกพัน ng-click บนปุ่มส่งในขณะที่ ng-submit คำสั่ง `sitted` บนฟอร์มจะเรียกใช้แฮนด์เลอร์สองครั้ง ครั้งละหนึ่งเหตุการณ์ เอกสารอ้างอิงอย่างเป็นทางการเตือนไม่ให้รวมแฮนด์เลอร์ทั้งสองเข้าด้วยกัน ดังนั้นควรเลือกใช้เพียงตัวเดียว
  • การส่งข้อมูลที่ไม่คาดคิด ปุ่มใดๆ ภายในแบบฟอร์มโดยไม่มี type="button" เรียกใช้งานอีเวนต์การส่งข้อมูล ทำเครื่องหมายปุ่มยกเลิกและปุ่มรีเซ็ตอย่างชัดเจน มิฉะนั้นปุ่มเหล่านั้นจะเรียกใช้งานตัวจัดการเหตุการณ์ด้วย

การเฝ้ารักษาการณ์ $valid เป็นเพียงความสะดวกสบาย ไม่ใช่มาตรการควบคุมความปลอดภัย ค่าต่างๆ ยังคงต้องได้รับการตรวจสอบความถูกต้องอีกครั้งบนเซิร์ฟเวอร์ก่อนที่จะถูกจัดเก็บ

คำถามที่พบบ่อย

ใช่แล้ว ฟอร์มที่มีช่องป้อนข้อมูลหรือปุ่มประเภท submit จะเรียกใช้งานอีเวนต์ submit เมื่อกดปุ่ม Enter ภายในช่องป้อนข้อมูล ดังนั้นนิพจน์ ng-submit จึงทำงานได้โดยไม่ต้องใช้ตัวจัดการปุ่มเพิ่มเติมใดๆ

ไม่ครับ เฉพาะองค์ประกอบฟอร์มเท่านั้นที่จะเรียกใช้เหตุการณ์ submit ที่ directive นั้นรับฟังอยู่ ย้าย ng-submit ไปไว้ในแท็กฟอร์ม หรือแนบ ng-click เข้ากับองค์ประกอบที่คุณต้องการให้มีการตอบสนองจริงๆ

ng-submit ไม่ส่งอาร์กิวเมนต์ใดๆ อ่านค่าคุณสมบัติขอบเขตที่ ng-model กำหนดค่าไว้ หรือส่งค่าเหล่านั้นโดยตรง เช่น ng-submit=”Display(Topic)” หรือ ng-submit=”Display(topicForm)”

ใช่แล้ว แต่ละองค์ประกอบของฟอร์มจะมีตัวควบคุมฟอร์มของตัวเอง ดังนั้นควรตั้งชื่อฟอร์มแต่ละฟอร์มให้ไม่ซ้ำกันและผูกตัวจัดการแยกต่างหาก การใช้ฟังก์ชันเดียวกันในหลายฟอร์มจะทำให้เกิดปัญหาขอบเขตการทำงานชนกัน

ตัวจัดการจะทำงานไม่ว่ากรณีใดๆ แต่ฟิลด์ที่ไม่มี ng-รุ่น ฟังก์ชันนี้จะไม่เขียนค่าลงในตัวแปร `$scope` ดังนั้นฟังก์ชันจึงไม่สามารถอ่านค่าได้ ควรผูกค่าอินพุตทุกตัวที่คุณวางแผนจะประมวลผล

คอมไพล์ฟอร์มในการทดสอบ ตั้งค่าโมเดลในขอบเขต เรียกใช้งานเหตุการณ์ส่งข้อมูล จากนั้นตรวจสอบอาร์เรย์หรือการเรียกใช้บริการที่แฮนด์เลอร์สร้างขึ้น Karma ยังคงเป็นคู่ที่นิยมใช้กันทั่วไป

โมเดลภาษาจะอ่านรูปร่างโมเดลและแบบร่างที่ต้องการ คุณลักษณะ ng-pattern และ ng-minlength รวมถึงข้อความที่ตรงกัน ซึ่งทำให้ AngularJS มีประสิทธิภาพมากขึ้น การตรวจสอบแบบฟอร์ม นำไปรวมไว้ในขั้นตอนการตรวจสอบ

นักบิน GitHub โหมดเอเจนต์จะเขียนเทมเพลตใหม่เป็น (ngSubmit) ด้วย FormGroup และสร้างคลาสคอมโพเนนต์ขึ้นมา แต่ตัวตรวจสอบความถูกต้องและการเรียกแบบอะซิงโครนัสที่สร้างขึ้นยังคงต้องการการตรวจสอบและการทดสอบจากมนุษย์

สรุปโพสต์นี้ด้วย: