Nhấp vào nút trong biểu mẫu gây ra làm mới trang


217

Tôi có một hình thức trong Angular có hai thẻ nút trong đó. Một nút gửi biểu mẫu trên ng-click. Nút còn lại hoàn toàn để điều hướng sử dụng ng-click. Tuy nhiên, khi nhấp vào nút thứ hai này, AngularJS đang gây ra việc làm mới trang sẽ kích hoạt 404. Tôi đã bỏ điểm dừng trong chức năng và nó đang kích hoạt chức năng của tôi. Nếu tôi làm bất kỳ điều nào sau đây, nó sẽ dừng:

  1. Nếu tôi loại bỏ ng-click, nút không gây ra làm mới trang.
  2. Nếu tôi nhận xét mã trong hàm, nó không gây ra làm mới trang.
  3. Nếu tôi thay đổi thẻ nút thành thẻ neo ( <a>) href="", thì nó không gây ra làm mới.

Cái sau có vẻ như là cách giải quyết đơn giản nhất, nhưng tại sao AngularJS thậm chí còn chạy bất kỳ mã nào sau chức năng của tôi khiến trang tải lại? Có vẻ như một lỗi.

Đây là mẫu:

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

Đây là phương pháp điều khiển:

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

Xem đây là vấn đề của bạn github.com/angular/angular.js/issues/1238 (Thật không may, tôi không biết cách của tôi xung quanh github đủ để có thể cho biết nếu sửa chữa này là trong phiên bản 1.0.1 hay không) .
Mark Rajcok

Tôi đã thấy cái đó, nhưng tôi không thay đổi địa điểm nên tôi không nghĩ nó được áp dụng. Trừ khi nút khác này bằng cách nào đó khiến nó gửi, nhưng nó không được xác định là loại gửi và khi tôi tắt ng-click, nút không gửi biểu mẫu.
chubbsondub

Thật tuyệt vời khi bạn có thể cung cấp một bản demo hoạt động cho vấn đề này. Có lẽ bắt đầu với: Angular Plnkr
Pete BD


Có vẻ như trùng lặp. stackoverflow.com/questions/16703215/...
Vaibs

Câu trả lời:


471

Nếu bạn có một cái nhìn về đặc tả W3C , có vẻ như điều rõ ràng cần thử là đánh dấu các yếu tố nút của bạn type='button'khi bạn không muốn chúng gửi.

Điều cần lưu ý đặc biệt là nơi nó nói

Một phần tử nút không có thuộc tính loại được chỉ định đại diện cho điều tương tự như một phần tử nút với thuộc tính loại được đặt thành "gửi"


4
Tôi gặp vấn đề tương tự như OP nhưng các nút của tôi có loại được chỉ định - và vẫn nhấp vào gây ra làm mới. Bất cứ nơi nào khác mà tôi có thể nhìn?
Mateo Velenik 3/2/2015

Điều đó cho tôi thấy rằng vấn đề của bạn là trong javascript. Vấn đề mà câu trả lời của tôi là giải quyết vấn đề nhiều hơn giữa dom và trình duyệt. Một số javascript xử lý nhấp vào nút của bạn có khả năng gây ra tải lại mà bạn thấy. Chúc mừng săn bắn;)
LOAS 4/2/2015

Điều này thật đúng với gì mà tôi đã tìm kiếm. Nó rất khó chịu trên trang của tôi vì nó được cho là chỉ hiển thị các lỗi và không gửi.
reaper_unique 17/03/2015

Tôi có các nút được đánh dấu bằng type = "nút" và cũng có vấn đề. Trong trình xử lý ng-click của tôi, tôi có $ event.stopPropagation (). Khi tôi gỡ bỏ nó, nó không tải lại. Tôi cần nó mặc dù. Bất cứ ý tưởng tại sao nó gây ra một trang tải lại?!
felixfbecker

@freshfelermo: cố gắng thêm $event.preventDefault(), điều đó đã giúp trong trường hợp của tôi. Nhưng tôi không có lời giải thích tại sao: - \
Tim Büthe

72

Bạn có thể cố gắng ngăn trình xử lý mặc định:

html:

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

js:

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

Đẹp! Nó thực sự lấy kịch bản của tôi!
Richard

2
Điều này làm việc cho chúng tôi, khi sử dụng AngularJS bên trong biểu mẫu SharePoint. Tôi đã phải thêm "event.stopPropagation ();" cũng như mặc dù.
Nick DeMayo

19

Bạn nên khai báo thuộc tính ng-submit={expression}trong <form>thẻ của bạn .

Từ các tài liệu ngSubmit http://docs.angularjs.org/api/ng.directive:ngSubmit

Cho phép các biểu thức góc ràng buộc với các sự kiện onsubmit.

Ngoài ra, nó ngăn chặn hành động mặc định (đối với biểu mẫu có nghĩa là gửi yêu cầu đến máy chủ và tải lại trang hiện tại).


3
Ngoài ra, hãy đảm bảo rằng bạn không có thuộc tính 'hành động' trên biểu mẫu: biểu mẫu (hành động = "/ đăng nhập", lng-submit = "login ()") Vì điều này sẽ làm cho trang được làm mới ngay cả khi bạn đã cài đặt ng-submit .
jenso

Gửi biểu mẫu và ngăn chặn hành động mặc định Vì vai trò của biểu mẫu trong các ứng dụng Angular phía máy khách khác với trong các ứng dụng khứ hồi cổ điển, nên trình duyệt không dịch dịch biểu mẫu thành một trang tải lại toàn bộ dữ liệu gửi đến máy chủ . Thay vào đó, một số logic javascript nên được kích hoạt để xử lý việc gửi biểu mẫu theo cách cụ thể của ứng dụng. Vì lý do này, Angular ngăn hành động mặc định (gửi biểu mẫu đến máy chủ) trừ khi phần tử <form> có thuộc tính hành động được chỉ định. - docs.angularjs.org/api/ng.directive:form
Jignesh Gohel

Tôi có một biểu mẫu với ng-submit = {biểu thức} và một nút có loại = "gửi". Hoạt động như chỉ tốt, ngoại trừ trên BB10. Nếu tôi sử dụng Gửi bàn phím BB10 thì trang sẽ làm mới. Nếu tôi sử dụng nút mà tôi đã khai báo ở dạng của mình thì nó hoạt động tốt.
Michael

Điều này không làm việc cho tôi. Tôi làm theo hướng dẫn chính xác. Trang vẫn đăng lại
meffect 13/2/2015

18

Tôi sử dụng chỉ thị để ngăn chặn hành vi mặc định:

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

Và sau đó, trong html:

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

Lệnh này cũng có thể được sử dụng với <a>và tất cả các thẻ khác


+1 Cảm ơn! Điều này hữu ích khi bạn không có quyền truy cập vào <form>thẻ và do đó không thể sử dụng lệnh ng-submitnày.
jackvsworld

yow cảm ơn vì điều này, nhưng tôi cũng cần hủy ng-click trong một chỉ thị
boi_echos 14/07/2015

Điều này cũng ngăn hình thức kích hoạt cuộc gọi lại ng-submit, phải không?
Jhourlad Estrella

5

Bạn có thể giữ <button type="submit">, nhưng phải loại bỏ thuộc tính action=""của <form>.


2

Tôi tự hỏi tại sao không ai đề xuất giải pháp đơn giản nhất có thể:

không sử dụng một <form>

Một <whatever ng-form>không IMHO một công việc tốt hơn và không có một hình thức HTML, không có gì để được nộp bởi trình duyệt riêng của mình là. Mà chính xác là hành vi đúng khi sử dụng góc.


Làm thế nào để thực thi formvalid khi nhấp mà không cần thẻ biểu mẫu?
Rizwan Patel

1
@RizwanPatel Tôi đoán, tôi không hiểu, nhưng với ng-form=someForm, bạn có $scope.someFormvà nó có một $validlĩnh vực. Vì vậy, tôi nhận được tất cả những gì tôi cần với <button ng-disabled="!someForm.$valid">.
maaartinus


1

Câu trả lời này có thể không liên quan trực tiếp đến câu hỏi. Nó chỉ dành cho trường hợp khi bạn gửi biểu mẫu bằng cách sử dụng tập lệnh.

Theo mã ng-nộp

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

  event.preventDefault();
};

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

Nó thêm trình lắng nghe sự kiện trên mẫu. Nhưng trình xử lý sự kiện sẽ không được gọi khi việc gửi được bắt đầu bằng cách gọi form.submit (). Trong trường hợp này, ng-submit sẽ không ngăn chặn hành động mặc định, bạn phải tự gọi ngăn chặn Default trong trình xử lý ng-submit;

Để cung cấp câu trả lời dứt khoát hợp lý, mục Thuật toán gửi biểu mẫu HTML 5 nêu rõ rằng một biểu mẫu chỉ gửi một sự kiện gửi nếu nó không được gửi bằng cách gọi phương thức gửi (có nghĩa là nó chỉ gửi một sự kiện gửi nếu được gửi bằng nút hoặc ẩn khác phương thức, ví dụ nhấn enter trong khi tiêu điểm nằm trên phần tử văn bản loại đầu vào).

Xem Biểu mẫu được gửi bằng cách sử dụng submit () từ một liên kết không thể bị bắt bởi trình xử lý onsubmit


0

Nút đầu tiên gửi biểu mẫu và nút thứ hai không

<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

Chỉ cần thêm FormsModulevào importsmảng của app.module.tstệp và thêm import { FormsModule } from '@angular/forms';ở đầu tệp này ... điều này sẽ hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.