我无法理解为什么应用程序正在进行多次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>
有线索的人吗?
答案 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')。