Ajax点击提交按钮时需要点击两次的问题

主要原因:Ajax的异步请求

原代码:

//发送网络请求登录接口
$.ajax({
    url: "./service/login.php",
    type: "POST",
    data: {
        username: $scope.username,
        password: $scope.password
    },
    success: function (data) {
        console.log(data);
        data = JSON.parse(data);
        if (data.code < 0){
            alert(data.message);
            return;
        }
        alert(data.message);
        $location.path('/home');
            },
    error: function (data) {
        console.log(data);
    }
});

方法一:Ajax异步变同步(ajax默认是异步请求)不推荐

使用异步请求的好处是在发起请求时不影响用户其他操作,而同步只有等到返回结果时才能继续操作。

$.ajax({
    url: "./service/login.php",
    type: "POST",
    async:false,
    data: {
        username: $scope.username,
        password: $scope.password
    },
    success: function (data) {
        console.log(data);
        data = JSON.parse(data);
        if (data.code < 0){
            alert(data.message);
            return;
        }
        alert(data.message);
        $location.path('/home');
            },
    error: function (data) {
        console.log(data);
    }
});

方法一虽然可以但是控制台报出警告,这种方法已经被废弃。

方法二:在$location.path(" ")后面加上$scope.$apply()。

使用$scope.$apply()原因如下:

AngularJS对JS原生的异步事件进行了封装:

  • Events => ng-click
  • Timeouts => $timeout
  • jQuery.ajax() => $http

这是一个传统的异步函数,仅仅在最后调用了$scope.$apply() 来通知AngularJS异步事件正在发生。

$scope.$apply()应该在尽可能接近异步事件绑定的地方被调用。

$scope.$apply() should occur as close to the async event binding as possible.

不要随意的在你的代码中使用它,如果你使用了if (!$scope.$$phase) $scope.$apply(),因为你没有处在调用栈的高层。

尽可能使用AngularJS的服务来代替原始的JS。如果你在创建一个AngularJS服务(例如为套接字创建服务),你应该在触发回调的任何位置都使用$scope.$apply()

注:不知道翻译的对不对,附上后两段的原文:

Do NOT randomly sprinkle it throughout your code. If you are doing 
if (!$scope.$$phase) $scope.$apply() it’s because you are not high enough in the call stack.

Whenever possible, use AngularJS services instead of native. If you’re creating an AngularJS service (such as for sockets) it should have a $scope.$apply() anywhere it fires a callback.

修改后代码:

$.ajax({
    url: "./service/login.php",
    type: "POST",
    // async:false,
    data: {
        username: $scope.username,
        password: $scope.password
    },
    success: function (data) {
        console.log(data);
        data = JSON.parse(data);
        if (data.code < 0){
            alert(data.message);
            return;
        }
        alert(data.message);
        $location.path('/home');
        $scope.$apply();
            },
    error: function (data) {
        console.log(data);
    }
});

方法三:angularJS $http服务

原文地址:https://blog.csdn.net/sky_lunar_g/article/details/71093142?tdsourcetag=s_pcqq_aiomsg

        function doLoginNg() {
            $http({
                method: 'post',
                url: '../service/login.php',
                data: {username: $scope.username, password: $scope.password},
                headers: {'Content-Type': 'application/x-www-form-urlencoded'},
                transformRequest: function (obj) {
                    var str = [];
                    for (var p in obj) {
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    }
                    return str.join("&");
                }
            }).then(function successCallback(response) {
                console.log(response);
                data = response.data
                //判断是否登录成功
                if (data.code < 0) {
                    alert(data.message);
                    return;
                }

                localStorage.setItem('username', data.content.username);
                $location.path('/home');

            }, function errorCallback(response) {
                console.log('失败');
            });
        }

猜你喜欢

转载自blog.csdn.net/weixin_42545184/article/details/83743564