2012-09-07 104 views
187

我在Angular中有一個表單,其中有兩個按鈕標籤。一個按鈕在ng-click上提交表格。另一個按鈕純粹用於導航,使用ng-click。但是,當點擊第二個按鈕時,AngularJS會導致頁面刷新,從而觸發404頁面。我已經在函數中刪除了一個斷點,並觸發了我的函數。如果我執行以下任何操作,它將停止:單擊表單中的按鈕會導致頁面刷新

  1. 如果我刪除ng-click,則該按鈕不會導致頁面刷新。
  2. 如果我註釋掉函數中的代碼,它不會導致頁面刷新。
  3. 如果我將按鈕標記更改爲href=""的定位標記(<a>),則不會導致刷新。

後者似乎是最簡單的解決方法,但爲什麼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"; 
}; 
+0

看看這是你的問題https://github.com/angular/angular.js/issues/1238 (不幸的是,我不知道我身邊的github的方式足以被能夠判斷這個修復是否在1.0.1版本中)。 –

+0

我看到一個,但我沒有改變位置,所以我不認爲它適用。除非這個按鈕以某種方式導致它提交,但它沒有被定義爲提交類型,並且當我脫離ng-click時,按鈕不會提交表單。 – chubbsondubs

+0

這將是偉大的,你可以提供這個問題的工作演示。也許從以下開始:[Angular Plnkr](http://plnkr.co/edit/gist:3662656) –

回答

399

如果你看看W3C specification,它會像要嘗試的最明顯的事情就是當你不想要的時候用type='button'來標記你的按鈕元素m提交。

特別要注意的一點是,它說

沒有指定類型屬性的按鈕元素表示同樣的事情,有其type屬性設置一個按鈕元素「提交」

+4

我與OP有同樣的問題,但我的按鈕具有指定類型 - 仍然單擊會導致刷新。任何其他我可以看的地方? –

+0

這表明你的問題在JavaScript中。我的答案正在解決的問題更多地是dom和瀏覽器之間的問題。處理按鈕點擊的一些JavaScript可能會導致您看到的重新加載。快樂狩獵;) – LOAS

+0

這正是我一直在尋找的。這在我的網頁上非常討厭,因爲它應該只顯示錯誤而不提交。 –

18

您應該聲明屬性ng-submit={expression}<form>標籤。

從ngSubmit文檔 http://docs.angularjs.org/api/ng.directive:ngSubmit

啓用結合角表達式的onsubmit事件。

此外,它可以防止默認操作(表單意味着將請求發送到服務器並重新加載當前頁面)。

+3

此外,請確保您沒有在窗體上設置'action'屬性:form(action =「/ login」,lng-submit =「login()」) 因爲這會使頁面刷新,即使您有ng - 提交集。 – jenso

+0

提交表單並阻止默認操作 由於客戶端Angular應用程序中的表單角色與傳統往返應用程序中的角色不同,因此瀏覽器不希望將表單提交轉換爲發送數據的完整頁面重新加載到服務器。相反,應該觸發一些JavaScript邏輯來以應用程序特定的方式處理表單提交。 因此,除非

元素具有指定的操作屬性,否則Angular會阻止默認操作(將表單提交到服務器)。 - http://docs.angularjs.org/api/ng.directive:form –

+0

我有一個ng-submit = {expression}的表單和一個type =「submit」的按鈕。除了在BB10上工作就好了。如果我使用BB10鍵盤的提交,則頁面將刷新。如果我使用我在窗體中聲明的按鈕,它可以正常工作。 – Michael

67

您可以嘗試以防止默認的處理程序:

HTML:

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

JS:

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

不錯!它真的取材於我的場景! – Richard

+2

在SharePoint表單中使用AngularJS時,這對我們有效。我不得不添加「event.stopPropagation();」儘管如此。 –

15

我使用的指令,以防止默認行爲:

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>使用和所有其它的標籤

+0

+1謝謝!當你不能訪問''標籤時,這很有用,因此不能使用'ng-submit'指令。 – jackvsworld

+0

非常感謝這個,但我還需要取消ng-click中的指令 –

+0

這也可以防止表單觸發ng-submit回調,對不對? –

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

你可以保持<button type="submit">,但必須刪除的屬性action=""<form>

2

我不知道爲什麼沒有人提出了可能的最簡單的解決方案:

不使用<form>

一個<whatever ng-form>確實恕我直言一個更好的工作,並沒有一個HTML表單,沒有什麼提交由瀏覽器本身。當使用角度時,這恰好是正確的行爲。

+0

如何在沒有表單標籤的情況下強制執行formvalid? –

+1

@RizwanPatel我想,我不明白,但是用'ng-form = someForm',你得到'$ scope.someForm',它有一個'$ valid'字段。所以我用'

0

將動作添加到您的表單中。

<form action="#">

0

這個答案可能並不直接相關的問題。只有在您使用腳本提交表單時才適用。

根據ng-submit code

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

 
    event.preventDefault(); 
 
}; 
 

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

它增加了表格上提交事件偵聽器。 但通過調用form.submit()提交時,不會調用提交事件處理程序。在這種情況下,ng-submit不會阻止默認操作,您必須在ng-submit處理程序中自己調用preventDefault;

爲了提供一個合理的明確的答案,在HTML表單提交算法的第5條規定,形式僅調度通過調用提交方法(這意味着它僅調度提交事件,如果提交如果沒有提交一個提交事件通過按鈕或其他隱式方法,例如在焦點位於輸入類型文本元素上時按下Enter鍵)。

Form submitted using submit() from a link cannot be caught by onsubmit handler