多个Ajax调用

时间:2014-08-20 13:46:01

标签: javascript angularjs

我无法理解为什么应用程序正在进行多次ajax调用。

看看这个指令:

gameApp.directive('mapActivity', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch(function(scope) {
                angular.element('.click#1').addClass('dotted').html($("<img src='images/dot.png'>"));
                var j = null;
                for(var i = 1; i <= 4; i++)
                {
                    $.ajax({
                        type: 'GET',
                        url: 'lib/terrain.php',
                        dataType: 'html',
                        data: {i: i},
                        success: function(data) {
                            var randomRuta = Math.floor((Math.random() * 100) + 1);
                            angular.element('.click#'+randomRuta).addClass('monster').html($("<img src='images/blackdot.png' title='"+data+"'>"));

                        },
                        error: function(xhr, ajaxOptions, thrownError) { alert(thrownError); }
                    });
                    j=i;
                }  
                angular.element('.click').click(function() {
                    if(angular.element(this).hasClass('monster'))
                    {
                        if(confirm('Vill du anfalla monster?'))
                        {
                            alert("Du vann");
                            angular.element('.click.monster'+j).empty();
                            angular.element('.click.monster').removeClass('monster'+j);

                            angular.element('.click.dotted').empty();
                            angular.element('.click.dotted').removeClass('dotted');
                            angular.element(this).addClass('dotted');
                            angular.element('.click.dotted').html($('<img src="images/dot.png">'));
                        }
                    }
                    else
                    {
                        angular.element('.click.dotted').empty();
                        angular.element('.click.dotted').removeClass('dotted');

                        if(!angular.element(this).hasClass('dotted'))
                        {
                            angular.element(this).addClass('dotted');
                            angular.element(this).html($('<img src="images/dot.png">'));
                        }
                    }
                });
            });                     
        }
    };
});

正如你所看到的,我有一个for循环,在for循环中,我有一个ajax-call函数。目的是为循环的每次迭代调用ajax方法4次。但相反,它被称为8次,就像第二次循环那样。

这是我的控制器:

var gameApp = angular.module("gameApp", ['ngRoute','ngSanitize']);

gameApp.service('link', function() {
    this.user = false;
});

gameApp.directive('mapActivity', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch(function(scope) {
                angular.element('.click#1').addClass('dotted').html($("<img src='images/dot.png'>"));
                var j = null;
                for(var i = 1; i <= 4; i++)
                {
                    $.ajax({
                        type: 'GET',
                        url: 'lib/terrain.php',
                        dataType: 'html',
                        data: {i: i},
                        success: function(data) {
                            var randomRuta = Math.floor((Math.random() * 100) + 1);
                            angular.element('.click#'+randomRuta).addClass('monster').html($("<img src='images/blackdot.png' title='"+data+"'>"));

                        },
                        error: function(xhr, ajaxOptions, thrownError) { alert(thrownError); }
                    });
                    j=i;
                }  
                angular.element('.click').click(function() {
                    if(angular.element(this).hasClass('monster'))
                    {
                        if(confirm('Vill du anfalla monster?'))
                        {
                            alert("Du vann");
                            angular.element('.click.monster'+j).empty();
                            angular.element('.click.monster').removeClass('monster'+j);

                            angular.element('.click.dotted').empty();
                            angular.element('.click.dotted').removeClass('dotted');
                            angular.element(this).addClass('dotted');
                            angular.element('.click.dotted').html($('<img src="images/dot.png">'));
                        }
                    }
                    else
                    {
                        angular.element('.click.dotted').empty();
                        angular.element('.click.dotted').removeClass('dotted');

                        if(!angular.element(this).hasClass('dotted'))
                        {
                            angular.element(this).addClass('dotted');
                            angular.element(this).html($('<img src="images/dot.png">'));
                        }
                    }
                });
            });                     
        }
    };
});

function makeTableFrom(str) {
    var k = 1;
    result = "";

    for(var i = 1; i <= 8; i++) {
        result += '<tr>';

        for(var j = 1; j <= 20; j++) {
            if(str[k] == '#') {
                result += '<td id=' + k + '">#</td>';
            }
            else if(str[k] == '&') {
                result += '<td class="click" val="water" id="' + k + '">&</td>';
            }
            else {
                result += '<td class="click" id="' + k + '"></td>';
            }

            k++;
        }
        result += '</tr>';
    }
    return result;
}


gameApp.config(function($routeProvider) {
    $routeProvider

    .when('/', {
            templateUrl : 'partials/firstpage.html',
            controller  : 'firstPageCtrl'
    })

    .when('/game', {
            templateUrl : 'partials/game.html',
            controller  : 'gameCtrl'
    });

});

gameApp.controller("firstPageCtrl", function($scope,$http,link,$location) {
    $scope.doLogin = function() {
        $http.post("lib/action.php", {username: $scope.username, password: $scope.password}).success(function(data) {
            if(data) {
                link.user = data;
                console.log(link.user);
                $location.path("/game");
            }
        }).error(function(data) {
            console.log(data);
        });
    };
});


gameApp.controller("gameCtrl", function($scope,$http,link,$location,$sce,$rootScope) {

    $scope.getMonsters = "1";

    $http.post("lib/action.php", {monsters: $scope.getMonsters}).success(function(data) {
        $scope.result = makeTableFrom(data);
    });

    $scope.safeHtml = function() {
        return $sce.trustAsHtml($scope.result);
    };
    if(link.user) {
        /*$scope.message = "fisk";
        console.log(link.user);*/
    } else {
        /*$scope.message = "Ledsen fisk";
        console.log("Är inte satt");*/
    }

});

这是我的HTML:

<div ng-controller="gameCtrl">
    <table ng-bind-html="safeHtml()" map-Activity>
    </table>
</div>

有线索的人吗?

1 个答案:

答案 0 :(得分:0)

makeTableFrom的响应到来之后,您似乎正在调用$http.post("lib/action.php"(构建您尝试操作的HTML)。 另一方面,mapActivity指令的link函数在响应到来之前执行。因此,angular.element('.click#1')所指的元素尚不存在。 通过将其包装在scope.$watch中,每当示波器上的某些内容发生变化时,您就会执行它。 $scope.result = makeTableFrom(data);肯定会更改范围内的某些内容,因此在响应到来之后会有一个angular.element('.click#1')匹配的元素(makeTableFrom刚创建它...)。 问题是scope.$watch内的整个代码在响应到来之前至少执行了一次。 你需要做的是重新考虑整个代码或采取短路和hacky路线,并检查你试图操纵的元素是否存在:

scope.$watch(function(scope) {
    if(angular.element('.click#1').size() > 0) {
        ...
    }  
}

整个scope.$watch想法错误的另一个原因是因为每次更改范围时都会执行它(`$ scope.foo ='bar')。