我正在阅读The Complete Book on AngularJS, Ari Lerner
书,在那里我找到了关于ng-class的this example。我在generateNumber()
函数中添加了一个额外的console.log。我看到它只记录了一次。
之后,我用x
函数调用替换了generateNumber()
使用的地方。在我的更改see this之后,我的代码看起来像这样:
HTML
<!doctype html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/foundation/4.3.2/css/foundation.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
</head>
<body>
<div ng-controller="LotteryController">
<div ng-class="{red: generateNumber() > 5}">
You won!
</div>
<button ng-click="generateNumber()">Draw Number</button>
<p>Number is: {{ x }}</p>
</div>
</body>
</html>
JS
angular.module('myApp', [])
.controller('LotteryController', function($scope) {
$scope.generateNumber = function() {
var num = Math.floor((Math.random()*10)+1);
console.log("Number: "+num);
$scope.x = num;
return num;
};
});
所以我无法理解为什么console.log()
被多次记录,甚至当我点击按钮它应该只记录一次但是它被记录了不止一次。我无法理解为什么多次调用该方法。有时我得到这个例外(我只粘贴了前两行)
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations:
这个$摘要是什么?以及它达到极限的原因。观察者是什么?并请说为什么多次进行日志记录? 谢谢你们,
修改
感谢回复人员,但我想使用像ng-class="{red: generateNumber() > 5}"
之类的东西。这样做有什么不对。谁能解释我这个。我不想在那里使用$scope.x
,所以你们现在可以忽略它。
谢谢你们,
答案 0 :(得分:1)
可能在每个摘要中验证了ng-class,并且您调用了一个方法,以便在循环中调用它。
要纠正错误:将x添加到范围变量中,然后调用generate number来初始化x
** HTML:**
<div ng-controller="LotteryController">
<div ng-class="{'red': x > 5}" ng-init="generateNumber()">
You won!
</div>
<button ng-click="generateNumber()">Draw Number</button>
<p>Number is: {{ x }}</p>
</div>
答案 1 :(得分:1)
在每个$ scope。$ digest上调用console.log,因为你使用$ scope.generateNumber方法作为ng-class的条件,内部generateNumber()修改$ scope.x变量,导致新的$ digest循环运行。
在每个$ digest循环中,调用生成数来确定是否应用该类。
使用$ scope.x作为ng-class的条件
angular.module('myApp', [])
.controller('LotteryController', function($scope) {
$scope.generateNumber = function() {
var num = Math.floor((Math.random()*10)+1);
console.log("Number: "+num);
$scope.x = num;
return num;
};
});
<!doctype html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/foundation/4.3.2/css/foundation.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
</head>
<body>
<div ng-controller="LotteryController">
<div ng-class="{red: x > 5}">
You won!
</div>
<button ng-click="generateNumber()">Draw Number</button>
<p>Number is: {{ x }}</p>
</div>
</body>
</html>
答案 2 :(得分:1)
根据doc:
处理当前范围及其子项的所有观察者。 因为观察者的监听器可以改变模型,所以$ digest()保持不变 打电话给观察者直到不再有听众开枪。这意味着 有可能进入无限循环。这个功能会 抛出'超出最大迭代次数'。如果迭代次数 超过10。
换句话说, $ digest 是您的视图与$ scope同步的过程。 摘要 启动后,它会一直循环,直到$scope
的状态与前一个周期的状态相比没有变化。
范围状态的变化是通过评估 监视 表达式(在视图中明确定义或隐含)来确定的。如果每个表达式在连续的周期内评估相同的结果,那么摘要将结束。
为了明确解决您的观察问题,generateNumber()
始终会返回一个新号码!因此, $ digest 进程始终会在每个周期结束时看到作用域的状态发生了变化。在经历了10个循环之后,系统猜测它处于无限循环中,因此它会在您观察时抛出异常(并且在文档中指定)。
您可以按照以下方法解决问题:
$scope.generateNumber = function () {
$scope.x = Math.floor((Math.random() * 10) + 1);
console.log("Number: " + $scope.x);
};
接下来应对您的标记进行以下更改:
<div ng-class="{red: x > 5}">
You won!
</div>
当我读到你在你的一条评论中说“我不想使用,x,直接”;那么只需创建一个返回类映射对象的方法,或者直接将类映射对象添加到作用域,或者添加一个将生成的数字返回给作用域的方法就足够了。
JS:
var number;
$scope.getNumber = function () {
return number;
};
$scope.generateNumber = function () {
$scope.x = Math.floor((Math.random() * 10) + 1);
number = $scope.x;
console.log("Number: " + $scope.x);
};
HTML
<div ng-class="getNumber() > 5">
You won!
</div>
JS:
var classMap = {};
$scope.getClassMap = function () {
classMap.red = $scope.x > 5;
return classMap;
};
HTML
<div ng-class="getClassMap()">
You won!
</div>
JS:
$scope.classMap = {};
$scope.generateNumber = function () {
$scope.x = Math.floor((Math.random() * 10) + 1);
$scope.classMap.red = $scope.x > 5;
console.log("Number: " + $scope.x);
};
HTML
<div ng-class="classMap">
You won!
</div>
答案 3 :(得分:0)
你在ng-class和ng-click中调用generateNumber()twise,这就是它多次记录的原因。检查ng-class的变化:
angular.module('myApp', [])
.controller('LotteryController', function($scope) {
$scope.generateNumber = function() {
var num = Math.floor((Math.random()*10)+1);
console.log("Number: "+num);
$scope.x = num;
return num;
};
});
<!doctype html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="//cdn.jsdelivr.net/foundation/4.3.2/css/foundation.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
</head>
<body>
<div ng-controller="LotteryController">
<div ng-class="{red: x > 5}">
You won!
</div>
<button ng-click="generateNumber()">Draw Number</button>
<p>Number is: {{ x }}</p>
</div>
</body>
</html>