使用范围时出错。$ watch in directive

时间:2014-08-20 12:15:35

标签: javascript angularjs dom error-handling

我在那里建立了一个使用范围的指令。$ watch。但是当我运行我的应用程序时出现以下错误:

Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.22/$rootScope/infdig?p0=10&p1=%5B%5B%22safeHtml()%3B%20newVal%3A%20%7B%7D%3B%20oldVal%3A%20%7B%7D%22%5D%2C%5B%22safeHtml()%3B%20newVal%3A%20%7B%7D%3B%20oldVal%3A%20%7B%7D%22%5D%2C%5B%22safeHtml()%3B%20newVal%3A%20%7B%7D%3B%20oldVal%3A%20%7B%7D%22%5D%2C%5B%22safeHtml()%3B%20newVal%3A%20%7B%7D%3B%20oldVal%3A%20%7B%7D%22%5D%2C%5B%22safeHtml()%3B%20newVal%3A%20%7B%7D%3B%20oldVal%3A%20%7B%7D%22%5D%5D

我不知道为什么会这样。我知道它与attr.ngBind有关,但我不知道为什么会触发这个错误。

这是我的控制器,包括我的指令:

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

gameApp.service('link', function() {
    this.user = false;
});
gameApp.filter('unsafe', function($sce) {
    return function(val) {
        return $sce.trustAsHtml(val);
    };
});

gameApp.directive('mapActivity', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
            scope.$watch(attr.ngBindHtml, function(value) {
            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)

如果您按照错误中的link进行操作,您会看到有关正在发生的事情的详细说明。您正在观看ngBindHtml以查找可能发生的任何更改。当您看到更改时,您通过手动更改html(添加/删除类,插入/删除内容)对$ watch中的更改做出反应。这些变化将再次触发手表。你创造了一个无限循环。你不应该在watch方法中改变你正在观察的变量。