การคลิกปุ่มภายในฟอร์มจะทำให้รีเฟรชหน้า


217

ฉันมีรูปแบบใน Angular ที่มีแท็กปุ่มสองปุ่มอยู่ในนั้น ng-clickปุ่มเดียวส่งแบบฟอร์มบน ปุ่มอื่น ๆ ng-clickเป็นอย่างหมดจดสำหรับการนำทางโดยใช้ อย่างไรก็ตามเมื่อคลิกปุ่มที่สองนี้ AngularJS จะทำให้เกิดการรีเฟรชหน้าซึ่งทำให้ทริกเกอร์ 404 ฉันได้หยุดพักเบรกพอยต์ในฟังก์ชัน ถ้าฉันทำอย่างใดอย่างหนึ่งต่อไปนี้มันจะหยุด:

  1. หากฉันลบng-clickปุ่มจะไม่ทำให้เกิดการรีเฟรชหน้า
  2. ถ้าฉันใส่ความคิดเห็นรหัสในฟังก์ชั่นก็ไม่ได้ทำให้การรีเฟรชหน้า
  3. หากฉันเปลี่ยนแท็กปุ่มเป็นสมอแท็ก ( <a>) ด้วยhref=""จะไม่ทำให้รีเฟรช

หลังดูเหมือนจะเป็นวิธีแก้ปัญหาที่ง่ายที่สุด แต่ทำไม AngularJS ถึงใช้รหัสใด ๆ หลังจากฟังก์ชั่นของฉันที่ทำให้หน้าโหลดซ้ำ? ดูเหมือนว่าแมลง

นี่คือแบบฟอร์ม:

<form class="form-horizontal" name="myProfile" ng-switch-when="profile">
  <fieldset>
    <div class="control-group">
      <label class="control-label" for="passwordButton">Password</label>
      <div class="controls">
        <button id="passwordButton" class="secondaryButton" ng-click="showChangePassword()">Change</button>
      </div>
    </div>

    <div class="buttonBar">
      <button id="saveProfileButton" class="primaryButton" ng-click="saveUser()">Save</button>
    </div>
  </fieldset>
</form>

นี่คือวิธีการควบคุม:

$scope.showChangePassword = function() {
  $scope.selectedLink = "changePassword";
};

ดูว่านี่เป็นปัญหาของคุณหรือไม่github.com/angular/angular.js/issues/1238 (น่าเสียดายที่ฉันไม่ทราบวิธีแก้ไข github พอที่จะบอกได้ว่าการแก้ไขนี้อยู่ในรุ่น 1.0.1 หรือไม่) .
Mark Rajcok

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

มันจะดีมากที่คุณสามารถให้ตัวอย่างการทำงานของปัญหานี้ อาจเริ่มต้นด้วย: Angular Plnkr
Pete BD


ดูเหมือนซ้ำกัน stackoverflow.com/questions/16703215/…
Vaibs

คำตอบ:


471

หากคุณได้ดูข้อมูลจำเพาะของ W3Cดูเหมือนว่าสิ่งที่ชัดเจนที่จะลองคือการทำเครื่องหมายองค์ประกอบปุ่มของคุณด้วยtype='button'เมื่อคุณไม่ต้องการให้พวกเขาส่ง

สิ่งที่ควรสังเกตเป็นพิเศษคือที่ที่มันบอกว่า

องค์ประกอบปุ่มที่ไม่มีการระบุแอตทริบิวต์แสดงถึงสิ่งเดียวกันกับองค์ประกอบปุ่มที่มีการกำหนดแอตทริบิวต์เป็น "ส่ง"


4
ฉันมีปัญหาเช่นเดียวกับ OP แต่ปุ่มของฉันมีประเภทที่ระบุ - และยังคงคลิกทำให้รีเฟรช สถานที่อื่น ๆ ที่ฉันสามารถมองเห็น?
Mateo Velenik

นั่นแสดงให้ฉันเห็นว่าปัญหาของคุณอยู่ในจาวาสคริปต์ ปัญหาที่คำตอบของฉันคือการพูดถึงคือเรื่องระหว่าง dom กับเบราว์เซอร์ จาวาสคริปต์บางตัวที่จัดการการคลิกปุ่มของคุณอาจทำให้เกิดการโหลดซ้ำที่คุณเห็น การล่าสัตว์ที่มีความสุข;)
LOAS

นี่คือสิ่งที่ฉันกำลังมองหา มันน่ารำคาญมากในหน้าของฉันเพราะมันควรจะแสดงข้อผิดพลาดและไม่ส่งเท่านั้น
reaper_unique

ฉันมีปุ่มที่ทำเครื่องหมายด้วย type = "button" และมีปัญหาด้วย ในตัวจัดการ ng-click ของฉันฉันมี $ event.stopPropagation () เมื่อฉันลบมันจะไม่โหลด ฉันต้องการมัน แนวคิดใดที่ทำให้หน้าโหลดซ้ำ!
felixfbecker

@freshfelicio: ลองเพิ่ม$event.preventDefault()ด้วยซึ่งช่วยในกรณีของฉัน แต่ฉันไม่มีคำอธิบายว่าทำไม: - \
Tim Büthe

72

คุณสามารถพยายามป้องกันตัวจัดการเริ่มต้น:

HTML:

<button ng-click="saveUser($event)">

js:

$scope.saveUser = function (event) {
  event.preventDefault();
  // your code
}

ดี! มันนำมาใช้กับสถานการณ์ของฉันจริงๆ!
ริชาร์ด

2
สิ่งนี้ใช้ได้กับเราเมื่อใช้ AngularJS ภายในฟอร์ม SharePoint ฉันต้องเพิ่ม "event.stopPropagation ();" เช่นกันว่า
Nick DeMayo

19

คุณควรประกาศคุณสมบัติng-submit={expression}ใน<form>แท็กของคุณ

จากเอกสาร ngSubmit http://docs.angularjs.org/api/ng.directive:ngSubmit

เปิดใช้งานการแสดงออกที่มีผลผูกพันเชิงมุมเพื่อส่งเหตุการณ์

นอกจากนี้ยังป้องกันการกระทำเริ่มต้น (สำหรับรูปแบบหมายถึงการส่งคำขอไปยังเซิร์ฟเวอร์และโหลดหน้าปัจจุบัน)


3
นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณไม่ได้ตั้งค่าคุณสมบัติ 'การกระทำ' ในแบบฟอร์ม: form (action = "/ login", lng-submit = "login ()") เนื่องจากสิ่งนี้จะทำให้การรีเฟรชหน้าแม้ว่าคุณจะมีชุด ng-submit .
jenso

การส่งแบบฟอร์มและป้องกันการกระทำเริ่มต้นเนื่องจากบทบาทของแบบฟอร์มในแอปพลิเคชัน Angular ฝั่งไคลเอ็นต์นั้นแตกต่างจากในแอปไปกลับแบบคลาสสิกจึงเป็นที่ต้องการสำหรับเบราว์เซอร์ที่จะไม่แปลการส่งแบบฟอร์มลงในโหลดหน้าเต็ม . ควรเรียกใช้ตรรกะจาวาสคริปต์เพื่อจัดการกับการส่งแบบฟอร์มด้วยวิธีเฉพาะของแอปพลิเคชัน ด้วยเหตุนี้ Angular ป้องกันการกระทำเริ่มต้น (การส่งแบบฟอร์มไปยังเซิร์ฟเวอร์) เว้นแต่ว่าองค์ประกอบ <form> จะมีการระบุแอตทริบิวต์การกระทำ - docs.angularjs.org/api/ng.directive:form
Jignesh Gohel

ฉันมีแบบฟอร์มที่มี ng-submit = {expression} และปุ่มที่มี type = "submit" ใช้งานได้ดียกเว้น BB10 หากฉันใช้การส่งของแป้นพิมพ์ BB10 หน้านั้นจะรีเฟรช ถ้าฉันใช้ปุ่มที่ฉันประกาศในแบบฟอร์มของฉันมันใช้งานได้ดี
Michael

นี่มันใช้งานไม่ได้สำหรับฉัน ฉันทำตามคำแนะนำอย่างแน่นอน หน้ายังโพสต์กลับ
meffect

18

ฉันใช้คำสั่งเพื่อป้องกันพฤติกรรมเริ่มต้น:

module.directive('preventDefault', function() {
    return function(scope, element, attrs) {
        angular.element(element).bind('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
        });
    }
});

จากนั้นใน html:

<button class="secondaryButton" prevent-default>Secondary action</button>

คำสั่งนี้สามารถใช้กับ<a>และแท็กอื่น ๆ ทั้งหมด


+1 ขอบคุณ! สิ่งนี้มีประโยชน์เมื่อคุณไม่สามารถเข้าถึง<form>แท็กดังนั้นจึงไม่สามารถใช้ng-submitคำสั่งได้
jackvsworld

ขอบคุณสำหรับสิ่งนี้ แต่ฉันต้องยกเลิก ng-click ในคำสั่งด้วย
boi_echos

นอกจากนี้ยังป้องกันไม่ให้แบบฟอร์มเรียกใช้การโทรกลับ ng-submit ใช่ไหม
Jhourlad Estrella


2

ฉันสงสัยว่าทำไมไม่มีใครเสนอวิธีแก้ปัญหาที่ง่ายที่สุด:

อย่าใช้ <form>

<whatever ng-form>ไม่ IMHO งานที่ดีขึ้นและไม่มีรูปแบบ HTML ที่มีอะไรที่จะต้องส่งมาจากเบราว์เซอร์ของตัวเองเป็น ซึ่งเป็นพฤติกรรมที่ถูกต้องเมื่อใช้เชิงมุม


วิธีการบังคับใช้ formvalid เมื่อคลิกแล้วไม่มีแท็กแบบฟอร์ม?
Rizwan Patel

1
@RizwanPatel ฉันเดาว่าฉันไม่เข้าใจ แต่ด้วยng-form=someFormคุณจะได้รับ$scope.someFormและมี$validช่อง <button ng-disabled="!someForm.$valid">ดังนั้นผมจึงได้รับทั้งหมดที่ฉันจำเป็นต้องมี
maaartinus


1

คำตอบนี้อาจไม่เกี่ยวข้องกับคำถามโดยตรง เป็นเพียงกรณีเมื่อคุณส่งแบบฟอร์มโดยใช้สคริปต์

ตามรหัส ng-submit

 var handleFormSubmission = function(event) {
  scope.$apply(function() {
    controller.$commitViewValue();
    controller.$setSubmitted();
  });

  event.preventDefault();
};

formElement[0].addEventListener('submit', handleFormSubmission);

มันเพิ่มส่งฟังเหตุการณ์ในแบบฟอร์ม แต่จะไม่เรียกใช้ตัวจัดการเหตุการณ์ส่งเมื่อเริ่มต้นการส่งโดยเรียก form.submit () ในกรณีนี้ ng-submit จะไม่ป้องกันการดำเนินการเริ่มต้นคุณต้องโทร PreventDefault ด้วยตัวคุณเองใน ng-submit handler

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

ดูแบบฟอร์มที่ส่งโดยใช้ submit () จากลิงก์ไม่สามารถจับได้โดย onsubmit handler


0

ปุ่มแรกส่งแบบฟอร์มและครั้งที่สองไม่ได้

<body>
<form  ng-app="myApp" ng-controller="myCtrl" ng-submit="Sub()">
<div>
S:<input type="text" ng-model="v"><br>
<br>
<button>Submit</button>
//Dont Submit
<button type='button' ng-click="Dont()">Dont Submit</button>
</div>
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Sub=function()
{
alert('Inside Submit');
}

$scope.Dont=function()
{
$scope.v=0;
}
});
</script>

</body>

0

เพียงแค่เพิ่มFormsModuleในimportsอาร์เรย์ของapp.module.tsไฟล์และเพิ่มimport { FormsModule } from '@angular/forms';ที่ด้านบนของไฟล์นี้ ... มันจะทำงาน

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