我需要从HTML页面执行以下活动:
Submit
register.html
但是,目前它的工作方式如下:1),2),3)正常工作。
用户在第一次单击Submit相应的消息时会得到警报窗口。
用户仅在Submit 再次 单击时获得打印的消息,但再次显示警告窗口。
如果我alert('Something')从JS中删除,则必须单击两次以将消息打印在register.html
alert('Something')
另外,我想提醒您注意,单击两次也会使服务器调用两次。它的行为就好像在服务器调用后已暂停,然后打印我应该单击“提交”的消息一样。
<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
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我提到了控制器:
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>
知道如何通过一次“提交”单击即可完成所有这些活动吗?
只需执行以下操作:$timeout在控制器中注入服务并将代码包装如下:
$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来获取数据并更新的$ scope变量msgalert),我们必须告诉Angular数据中已有更改。
msgalert
因此,在您从服务器获得响应并更新了之后msgalert,Angular不会意识到该更改,因为它不在Angular的上下文之外,因此触发了Angular的新摘要循环,并且视图未更新。
之所以会这样,是因为当您再次单击表单中的“提交”按钮时,将在后台触发Angular的摘要循环,然后显示您的实际消息。
为了解决这个问题,我们使用服务将您的自定义(外部角度上下文)代码包装到Angular的上下文中,该$timeout服务立即通知Angular值msgalert已更改
(可选)您可以$scope.$apply()在if-else条件之后编写after,但是有时会引发异常,digest cycle is already in progress因为调用$scope.$apply(),我们会手动触发Angular的摘要周期。这就是为什么$timeout服务更清洁的原因。
$scope.$apply()
if-else
digest cycle is already in progress
更新资料
请注意,您根本不需要使用jQuery来进行AJAX调用。Angular提供$http服务,使用它您将根本不会遇到该问题。您可以这样编写代码:
$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 }); };