使用HTML5历史记录API会导致angularjs中出现未知错误

时间:2014-03-13 14:03:25

标签: javascript angularjs html5-history

在我的基于angularjs的应用程序中,我使用HTML5历史记录API来记录我点击过的链接的历史记录。

 history.pushState(null, null, '/meeting/site/');

每当我将这行代码放在angularjs中时,控制台都会发出错误消息

Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.7/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3A…ce%3D!1%3Breturn%20l%7D%3B%20newVal%3A%20210%3B%20oldVal%3A%20209%22%5D%5D
    at Error (<anonymous>)
    at http://localhost/js/vendor/angular.min.js:6:449
    at h.$digest (http://localhost/js/vendor/angular.min.js:101:152)
    at h.$apply (http://localhost/js/vendor/angular.min.js:103:100)
    at http://localhost/js/vendor/angular.min.js:74:474 

我不知道导致此错误的原因是什么?

1 个答案:

答案 0 :(得分:1)

infdig错误意味着&#34; Infinite digest&#34;,这意味着摘要周期永远不会停止。要理解这意味着什么,您需要了解摘要周期的工作原理。

Angular基于&#34;脏检查&#34;,摘要周期是Angular迭代范围内的所有属性以查看哪些已更改。如果任何属性发生了变化,它会触发所有属性的手表,让他们知道发生了什么事。由于手表可以更改示波器的属性,因此在手表完成后,Angular会进行另一轮脏检查。摘要循环在遍历所有属性时停止,并且它看到它们都没有更改。当手表始终为属性设置新值时,会发生无限摘要。这样的事情可能会更好地解释它:

$scope.myNumber = Math.random();
$scope.$watch('myNumber', function() {
  $scope.myNumber = Math.random();
});

也就是说,我们的手表永远不会停止被调用,因为它始终会改变myNumber的值。导致错误的另一个常见原因是,当您有两个属性和两个监视时,如下所示:

$scope.prop1 = Math.random();
$scope.prop2 = Math.random();

$scope.$watch('prop1', function() {
  $scope.prop2 = Math.random();
});
$scope.$watch('prop2', function() {
  $scope.prop1 = Math.random();
});

这些手表将在无限循环中相互触发。

现在,这并没有解释为什么你会收到错误,但我猜你还没告诉Angular你使用的是历史API,而不是默认的hashbang。你可以通过致电$locationProvider.html5Mode(true);来做到这一点。像这样:

myApp.config(function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider
    .when('/page1', { template: 'page1.html', controller: 'Page1Ctrl' })
    .when('/page2', { template: 'page2.html', controller: 'Page2Ctrl' })
});

您不应该直接拨打history.pushState(),而是使用Angulars $location服务,这样可以让Angular知道您何时修改位置。