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";
};
chubbsondubs
sumber
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
Sepertinya duplikat. stackoverflow.com/questions/16703215/…
Vaibs

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"

LOAS
sumber
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
}
antage
sumber
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).

Shane Stillwell
sumber
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

pleerock
sumber
+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>.

Anderson Ferreira
sumber
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.

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

Tambahkan tindakan ke formulir Anda.

<form action="#">

Swapnil Patwa
sumber
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

pengguna1577263
sumber
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>
Amay Kulkarni
sumber
0

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

Sahil Sharma
sumber