Mengklik tombol dalam formulir menyebabkan penyegaran halaman


217

Saya memiliki formulir di Angular yang memiliki dua tag tombol di dalamnya. Satu tombol mengirimkan formulir ng-click. Tombol lainnya murni untuk navigasi menggunakan ng-click. Namun, ketika tombol kedua ini diklik, AngularJS menyebabkan refresh halaman yang memicu 404. Saya telah menjatuhkan breakpoint pada fungsi dan itu memicu fungsi saya. Jika saya melakukan salah satu dari yang berikut ini, itu akan berhenti:

  1. Jika saya menghapus ng-click, tombol tidak menyebabkan penyegaran halaman.
  2. Jika saya berkomentar kode dalam fungsi, itu tidak menyebabkan penyegaran halaman.
  3. Jika saya mengubah tag tombol menjadi anchor tag ( <a>) dengan href="", maka itu tidak menyebabkan penyegaran.

Yang terakhir sepertinya solusi yang paling sederhana, tetapi mengapa AngularJS bahkan menjalankan kode apa pun setelah fungsi saya yang menyebabkan halaman dimuat ulang? Sepertinya ada bug.

Ini formulirnya:

<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>

Berikut adalah metode pengontrol:

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

Lihat apakah ini masalah Anda github.com/angular/angular.js/issues/1238 (Sayangnya, saya tidak tahu cara saya cukup sekitar github untuk dapat mengetahui apakah perbaikan ini dalam rilis 1.0.1 atau tidak) .
Mark Rajcok

Saya melihat itu, tapi saya tidak mengubah lokasi jadi saya pikir itu tidak berlaku. Kecuali jika tombol lain ini menyebabkannya mengirimkan, tapi itu tidak didefinisikan sebagai jenis pengiriman, dan ketika saya melepas ng-klik tombol tidak mengirimkan formulir.
chubbsondubs

Alangkah baiknya jika Anda bisa memberikan demo masalah ini. Mungkin dimulai dengan: Angular Plnkr
Pete BD


Jawaban:


471

Jika Anda melihat spesifikasi W3C , sepertinya hal yang jelas untuk dicoba adalah menandai elemen tombol type='button'Anda ketika Anda tidak ingin mereka mengirimkannya.

Hal yang perlu diperhatikan secara khusus adalah di mana dikatakan

Elemen tombol tanpa atribut tipe yang ditentukan mewakili hal yang sama dengan elemen tombol dengan atribut tipenya disetel ke "kirim"


4
Saya memiliki masalah yang sama dengan OP tetapi tombol saya memiliki tipe yang ditentukan - dan masih klik menyebabkan penyegaran. Adakah tempat lain di mana saya bisa melihat?
Mateo Velenik

Itu menunjukkan kepada saya bahwa masalah Anda adalah dalam javascript. Masalahnya jawaban saya adalah lebih banyak masalah antara dom dan browser. Beberapa javascript yang menangani klik tombol Anda kemungkinan menyebabkan memuat ulang yang Anda lihat. Selamat berburu;)
LOAS

Ini persis apa yang saya cari. Itu sangat menjengkelkan pada halaman saya karena seharusnya hanya menampilkan kesalahan dan tidak mengirimkan.
reaper_unique

Saya memiliki tombol saya ditandai dengan tipe = "tombol" dan memiliki masalah juga. Di penangan ng-klik saya, saya punya $ event.stopPropagation (). Ketika saya menghapusnya, itu tidak memuat ulang. Saya membutuhkannya. Adakah ide mengapa ini menyebabkan halaman dimuat ulang ?!
felixfbecker

@ freshfelicio: coba juga tambahkan $event.preventDefault(), yang membantu dalam kasus saya. Tapi saya tidak punya penjelasan mengapa: - \
Tim Büthe

72

Anda dapat mencoba mencegah penangan default:

html:

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

js:

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

Bagus! Itu benar-benar sesuai dengan skenario saya!
Richard

2
Ini berfungsi untuk kami, saat menggunakan AngularJS di dalam formulir SharePoint. Saya memang harus menambahkan "event.stopPropagation ();" juga.
Nick DeMayo

19

Anda harus mendeklarasikan atribut ng-submit={expression}dalam <form>tag Anda .

Dari dokumen ngSubmit http://docs.angularjs.org/api/ng.directive:ngSubmit

Memungkinkan pengikatan ekspresi sudut untuk mengirimkan peristiwa.

Selain itu mencegah tindakan default (yang untuk formulir berarti mengirim permintaan ke server dan memuat ulang halaman saat ini).


3
Juga, pastikan Anda tidak memiliki properti 'aksi' diset pada formulir: form (action = "/ login", lng-submit = "login ()") Karena ini akan membuat halaman menyegarkan bahkan jika Anda memiliki ng-kirim set .
jenso

Mengirimkan formulir dan mencegah tindakan default Karena peran formulir dalam aplikasi Angular sisi-klien berbeda dari pada aplikasi bolak-balik klasik, browser diinginkan untuk tidak menerjemahkan pengiriman formulir ke dalam reload halaman penuh yang mengirimkan data ke server . Sebaliknya beberapa logika javascript harus dipicu untuk menangani pengiriman formulir dengan cara khusus aplikasi. Karena alasan ini, Angular mencegah tindakan default (pengiriman formulir ke server) kecuali elemen <form> memiliki atribut tindakan yang ditentukan. - docs.angularjs.org/api/ng.directive:form
Jignesh Gohel

Saya memiliki formulir dengan ng-submit = {ekspresi} dan tombol dengan tipe = "kirim". Bekerja dengan baik kecuali pada BB10. Jika saya menggunakan keyboard BB10 Kirim maka halaman akan menyegarkan. Jika saya menggunakan tombol yang telah saya nyatakan dalam formulir saya itu berfungsi baik.
Michael

Ini tidak bekerja untukku. Saya mengikuti petunjuknya dengan tepat. Halaman masih memposting kembali
meffect

18

Saya menggunakan arahan untuk mencegah perilaku default:

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

Dan kemudian, dalam html:

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

Arahan ini juga dapat digunakan dengan <a>dan semua tag lainnya


+1 Terima kasih! Ini membantu ketika Anda tidak memiliki akses ke <form>tag dan karenanya tidak dapat menggunakan ng-submitarahan.
jackvsworld

yow terima kasih untuk yang satu ini, tapi saya juga harus membatalkan ng-klik di arahan
boi_echos

Ini juga mencegah formulir dari memicu panggilan balik ng-submit, kan?
Jhourlad Estrella

5

Anda dapat menyimpan <button type="submit">, tetapi harus menghapus atribut action=""dari <form>.


2

Saya heran mengapa tidak ada yang mengusulkan solusi yang paling sederhana:

jangan gunakan a <form>

A <whatever ng-form>tidak IMHO pekerjaan yang lebih baik dan tanpa bentuk HTML, tidak ada yang dikirimkan oleh browser itu sendiri. Perilaku yang persis tepat saat menggunakan sudut.


bagaimana cara menegakkan formvalid di klik lalu tanpa tag formulir?
Rizwan Patel

1
@RizwanPatel Saya kira, saya tidak mengerti, tetapi dengan ng-form=someForm, Anda dapatkan $scope.someFormdan memiliki $validbidang. Jadi saya mendapatkan semua yang saya butuhkan <button ng-disabled="!someForm.$valid">.
maaartinus


1

Jawaban ini mungkin tidak terkait langsung dengan pertanyaan. Ini hanya untuk kasus ketika Anda mengirimkan formulir menggunakan skrip.

Menurut ng-kirim kode

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

  event.preventDefault();
};

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

Itu menambahkan mengirimkan pendengar acara di formulir. Tetapi ajang event handler tidak akan dipanggil ketika ajukan diawali dengan memanggil form.submit (). Dalam hal ini, ng-kirim tidak akan mencegah tindakan default, Anda harus memanggil preventDefault sendiri di ng-submit handler;

Untuk memberikan jawaban yang cukup pasti, Algoritma Pengajuan Formulir HTML item 5 menyatakan bahwa formulir hanya mengirim acara pengiriman jika tidak dikirim dengan memanggil metode kirim (yang berarti hanya mengirimkan acara pengiriman jika diserahkan oleh tombol atau implisit lainnya) metode, misalnya menekan enter saat fokus pada elemen teks tipe input).

Lihat Formulir yang dikirimkan menggunakan submit () dari tautan yang tidak dapat ditangkap oleh onsub handler


0

Tombol Pertama mengirimkan formulir dan yang kedua tidak

<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

Cukup tambahkan FormsModuledalam importsarray app.module.tsfile, dan tambahkan import { FormsModule } from '@angular/forms';di bagian atas file ini ... ini akan berfungsi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.