AngularJS 与 Ajax 表单提交需要点击两次

2023-12-02

我需要从 HTML 页面执行以下活动:

  1. 用户输入电子邮件和密码进行注册
  2. 当用户点击时表单被发送到控制器Submit
  3. Control 使用 AJAX 创建对 RESTful Server 的 JSON 请求, 服务器做出相应响应。
  4. 根据服务器的响应,用户应该收到警报窗口,并且 当前页面上打印的消息(register.html)位于“提交”下方。 如果是“成功-已注册”或“失败-无法注册” 登记”。

但是,目前它的工作方式如下:1)、2)、3)按预期工作。

  1. 用户第一次点击时会收到警报窗口Submit并附上适当的消息。

  2. 用户仅在单击时才会打印消息Submit AGAIN,但再次显示警报窗口。

如果我删除alert('Something')从 JS 中,我必须单击两次才能将消息打印在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';
                }
            }
        });
    };
});

Also in 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在您的控制器中提供服务并包装您的代码,如下所示:

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,Angular 不知道该更改,因为它位于 Angular 上下文之外,因此会触发 Angular 新的摘要周期,并且视图不会更新。

为什么你会看到这个,当你再次点击表单中的提交按钮时,Angular 的摘要循环会在幕后触发,然后你的实际消息就会显示出来。

为了解决这个问题,我们使用以下方法将您的自定义(角度上下文之外)代码包装到 Angular 的上下文中:$timeout立即通知 Angular 中的值的服务msgalert已经改变

或者,您可以编写$scope.$apply()在你之后if-else条件但有时会引发异常digest cycle is already in progress因为打电话$scope.$apply(),我们手动触发 Angular 的摘要周期。这就是为什么更清洁的方法是$timeout服务。

Update

请注意,您根本不必使用 jQuery 来执行 AJAX 调用。角有$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
    });
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AngularJS 与 Ajax 表单提交需要点击两次 的相关文章

  • 如何在 Google 地图上旋转叠加图像?

    我正在尝试将一系列叠加层放置到 Google 地图上 我正在跟随地面覆盖层的示例代码 https developers google com maps documentation javascript examples groundover
  • GraphQL 错误字段类型必须是输入类型,但得到:

    这是突变 const createNotebook mutationWithClientMutationId name CreateNotebook inputFields token type GraphQLString details
  • jQuery onclick 隐藏其父元素[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想隐藏 li tag on a 使
  • a:not(a:not([href])) 选择器

    我希望无论何时 某个操作都与锚标记的点击事件相关联href属性 不开始于mailto and 不以 and 存在任何值 包括空 所以我正在尝试这段代码 a href example com example com a a href Some
  • 暂停或停止整页而不破坏

    我有一个正常滚动的页面 页面上有一个锚点 它会弹出一个模式 我在其中初始化 fullpage js 到目前为止 效果很好 但是当用户单击关闭图标时 我希望模式窗口关闭 并使 fullpage js 暂停或停止 以便禁用全页滚动效果 除非用户
  • 如何转义 onClick 处理程序内 JavaScript 代码中的字符串?

    也许我只是想得太难了 但我在弄清楚链接的 onClick 处理程序内的某些 JavaScript 代码中的字符串上使用什么转义时遇到了问题 例子 a href Select a The and 是发生模板替换的地方 我的问题是项目名称可以包
  • 脚本不会从nodejs应用程序中的ejs文件运行

    我正在尝试使用nodejs express mysql和ejs让网页显示图表 但我显然不明白ejs javascript等是如何工作的 我需要运行一个脚本来设置图表 来自 Chart js 模块 但它不会输出任何类型的图表 我尝试过的 将
  • 尝试将远程图像转换为 Base64 数据时出现 CORS 错误[重复]

    这个问题在这里已经有答案了 我需要将远程图像转换为给定其 URL 的 base64 但我遇到了 CORS 错误 并且不确定如何解决 我遵循了这个问题的一些解决方案 如何使用javascript将图像转换为base64字符串 https st
  • 从组件刷新/重新加载 ember 路由

    我有一个组件 它实际上是一个模式对话框 当我完成该对话框并按 确定 按钮时 我想留在打开该对话框的停留页面上 这并不难 但问题是该对话框更改了数据 我通过 REST 调用获取数据 因此我需要刷新已经所在的路线以反映数据更改 因为我是从组件中
  • 过滤数据表中的行

    我目前的 JQuery 插件 DataTables 工作正常 并且我在页面顶部插入了一个按钮来进一步过滤列表 我还使用了 DataTables 内置的搜索栏 我希望按钮向下过滤表格 并只显示包含特定值的行 下面是我一直在做的事情 但似乎没有
  • React cloneElement 未设置键

    我正在构建一个动态生成键的表控件 我理解这可能不是一个好主意 我想键应该与其代表的数据唯一关联 否则 React 只能为我们生成唯一的 id 但无论哪种方式似乎没有设置按键 我不知道为什么 表中的行是用可以找到的函数生成的here http
  • Javascript - HTML Canvas 上的 Gecko 边框半径自适应(CSS border-radius)

    我试图弄清楚如何将 border radius css 属性的行为重现到 HTML 画布中 所以我已经在 J avascript 中做了一些事情 以便使用特定的半径 对于每个角 来计算给定形状的正确边界 如果需要的话 这是上一个问题 Gec
  • Javascript - 通过键获取特定 JSON 数组元素内的属性值

    我有一个像这样的 JSON 结构 map key1 valueA1 key2 valueA2 key3 valueA3 key1 valueB1 key2 valueB2 key3 valueB3 key1 valueC1 key2 val
  • AngularJS 的 HEAD 与 BODY

    在所有 AngularJS 示例中 Angular 库都放置在文档的 HEAD 标签中 我有一个基于 HTML5 Boilerplate 布局构建的现有项目 这定义了 JS 库应该放置在 DOM 的最底部 在 tag AngularJS需要
  • 帮助使用 jquery 验证插件和复选框

    我有一个复选框组 需要对其进行唯一命名 以将值单独存储在数据库中 但是 使用 jquery 验证插件 我无法验证名称不同的组
  • Promise链基本问题

    我正在尝试理解 Promise 我创建了一些有效的承诺链 而另一些则无效 我已经取得了进步 但显然缺乏基本概念 例如 以下承诺链不起作用 这是一个愚蠢的例子 但说明了问题 我正在尝试在链中使用 Node 的函数 randomBytes 两次
  • chrome中使用jquery的图像高度问题

    img height 回报0在 Chrome 中 但在 IE 和 Firefox 中返回实际高度 在 Chrome 中获取图像高度的实际方法是什么 正如 Josh 提到的 如果图像尚未完全加载 jQuery 将不知道尺寸是多少 尝试这样的操
  • 如何防止 Bootstrap Navbar Toggle 下推内容?

    我将 Bootstrap 与静态顶部导航栏一起使用 如下所示
  • 单击即可切换背景颜色和过渡

    这看起来应该很容易 但我真的找不到办法做到这一点 动画 http doir ir css gif http doir ir css gif 当您单击这些相应的链接时 我需要更改和过渡页面的背景颜色 我见过的最接近触发这种类型转换的事情是 仅
  • 如何从索引文件迭代多个导入的模块

    我有一个名为Polygons我在那里创建了一个index jsfile 以导出目录中的所有文件 它看起来像这样 export default as europe from europe export default as northAmer

随机推荐