2015-11-19 87 views
3

我需要從我的HTML頁面做了以下活動:AngularJS使用Ajax表單提交需要點擊兩次

  1. 用戶輸入電子郵件地址和密碼來註冊
  2. 形式發送到控制器的時候,用戶點擊Submit
  3. 控件使用AJAX爲RESTful Server創建JSON請求,並且 服務器做出相應響應。
  4. 根據服務器的迴應,用戶應該在「提交」下面的當前頁面(register.html)上得到警報窗口和一條 消息。 如果它是「成功 - 註冊」或「失敗 - 不能 註冊」。

但是,目前它正在像這樣工作:1),2),3)按預期工作。

  1. 用戶首先用適當的消息點擊Submit獲取警報窗口。

  2. 用戶只能點擊打印的郵件SubmitAGAIN,但再次顯示警報窗口。

如果我從JS刪除alert('Something'),我要爲消息中單擊兩次打印在register.html

另外,我想將它帶到你的注意,點擊兩次也正在調用服務器的兩倍。它的行爲就好像它在服務器調用後暫停,然後打印我應該點擊提交的消息。

register.html

<div class='container'> 
    <div class='col-md-12'> 
     <div class='fill' ng-controller="registerController"> 
      <form name="userForm" ng-submit="submitForm(userForm.$valid,user)" novalidate> 
       <!-- ALL FORM ELEMENTS HERE --> 
       <button type="submit" class="btn btn-primary" ng-disabled="userForm.$invalid" ng-click="showme=true"> 
        Submit 
       </button> 
       <div class="wrapper"> 
        <h3 ng-show="showme"><em>{{msgalert}}</em></h3> 
       </div> 
      </form> 
     </div> 
    </div> 
</div> 

我的JS控制器看起來像這樣stackoverflow_q3.js

// create angular controller 
var register = angular.module('Main-app'); 
register.controller('registerController', function ($scope, $http, $location) { 

    // function to submit the form after all validation has occurred    
    $scope.submitForm = function (isValid, user) { 
     console.log('Stackoverflow JS func caled'); 
     var regData = { 
      "email": user.email, 
      "password": user.password1 
     }; 

     var jsonData = JSON.stringify(regData); 
     var request = $.ajax({ 
      url: 'myurl', 
      type: 'POST', 
      data: jsonData, 
      headers: { 
       'Accept': 'application/json', 
       'Content-Type': 'application/json' 
      }, 
      dataType: 'json', 
      complete: function (response) { 
       console.log(response.responseText); 
       if (response.responseText == 'success') { 
        console.log('Registration Success'); 
        alert('Success'); 
        $scope.msgalert = 'Registration Success, Proceed to Login and Continue'; 
       } else if (response.responseText == 'fail') { 
        alert('registration failed'); 
        $scope.msgalert = 'Registration Failed, Please try again'; 
       } 
      } 
     }); 
    }; 
}); 

另外在index.html我所提到的控制器:

<!-- HTML --> 
<!DOCTYPE html> 
<html ng-app="Main-app"> 
<!-- Controllers --> 
<script src="js/controllers/stackoverflow_q3.js" type="text/javascript"></script> 

    <!-- Other elements --> 

</html> 

任何想法,我該怎麼辦所有這些活動在一個「提交」點擊?

+0

而不是'ng-show = showme',試試'ng-show = msgalert'。 – jperezov

+1

另外,你爲什麼要調用angular的'$ http'函數,但使用jQuery的'ajax'函數?一般來說,你需要在角度上創建一個服務(https://docs.angularjs.org/guide/services),並在你的控制器中調用_that_。 – jperezov

+0

是的,喬納森,你是對的,我同意這一點。我的錯。 – AdityaHandadi

回答

4

只是這樣做:在你的控制器注入$timeout服務和包裝你的代碼如下:

complete: function(response) { 
    console.log(response.responseText); 
    $timeout(function() { 
     if (response.responseText == 'success') { 
      console.log('Registration Success'); 
      alert('Success'); 
      $scope.msgalert = 'Registration Success, Proceed to Login and Continue'; 

     } else if (response.responseText == 'fail') { 
      alert('registration failed'); 
      $scope.msgalert = 'Registration Failed, Please try again'; 
     } 
    }); 
} 

此外,改變你的HTML代碼:

<h3 ng-show="msgalert"><em>{{msgalert}}</em></h3> 

所以存在的概念Angular中的消化循環。如果你在Angular的上下文之外做一些事情(比如你正在使用jQuery AJAX來獲取數據並更新msgalert的$ scope變量),我們必須告訴Angular數據中的某些內容已經改變。

因此,當您從服務器獲得響應並更新msgalert後,Angular不知道該更改,因爲它不在Angular的上下文中,因此Angular的新摘要循環被觸發並且視圖未更新。

爲什麼你看到這是,當你再次單擊表單中的提交按鈕,然後在場景後面觸發一個Angular的摘要循環,然後你的實際消息就會顯示出來。

爲了解決這個問題,我們裹着您的自定義(角範圍以外)代碼到使用$timeout服務,立即通知角,在msgalert值已更改

可選的角度的情況下,你可以寫$scope.$apply()在你的if-else條件之後,但它會拋出一個異常,有時候digest cycle is already in progress因爲調用$scope.$apply(),我們手動觸發了Angular的摘要循環。這就是爲什麼更清潔的方法是$timeout服務。

更新

請注意,您不必使用jQuery在所有這樣做AJAX調用。 Angular擁有$http服務並使用它,你根本不會面對這個問題。你可以這樣寫你的代碼:

$scope.submitForm = function (isValid, user) { 
    var regData = { 
     email: user.email, 
     password: user.password1 
    }; 

    $http({ 
     method: "POST", 
     url: "myurl", 
     data: regData,   // You don't need to stringify it and no need to set any headers 
    }).then(function (response) { 
     // Success callback 
     console.log(response.responseText); 
     if (response.responseText == 'success') { 
      $scope.msgalert = 'Registration Success, Proceed to Login and Continue'; 
     } else if (response.responseText == 'fail') { 
      $scope.msgalert = 'Registration Failed, Please try again'; 
     } 
    }, function() { 
     // Error callback 
    }); 
}; 
+0

太棒了!這絕對有效。我讀過關於http的內容,但由於某種原因,它給了我錯誤信息。現在我知道消息摘要的概念了,我會再次執行。謝謝! – AdityaHandadi

+0

很高興這有幫助,你明白這一點:-) –

+0

當我試圖實現$ HTTP,就像你提到的,它給了我這個錯誤'SyntaxError:在Object.parse意外的令牌(本地)' – AdityaHandadi

2

你的實際問題是jQuery AJAX的用法。通常,當角度$ http進行AJAX調用時,它在內部調用scope.digest循環,同時發現ajax響應。但在這裏你調用jQuery的Ajax,所以棱角無法消化的變化,所以綁定不起作用。

完成方法完成之前,請嘗試以下操作。

$ scope。$ apply();

如下

complete: function(response) { 
       console.log(response.responseText); 
       if(response.responseText == 'success'){ 
       console.log('Registration Success'); 
        alert('Success'); 
        $scope.msgalert='Registration Success, Proceed to Login and Continue'; 

       } 
       else if(response.responseText == 'fail'){ 
       alert('registration failed'); 
       $scope.msgalert='Registration Failed, Please try again'; 

       } 
       $scope.$apply(); 
} 

但最好是使用的$ HTTP,因爲它調用$範圍。$適用()內。

+0

這絕對適合我。謝謝! – AdityaHandadi

相關問題