为什么我的Angular函数在无限循环中被调用?
Why does my Angular function is called in infinite loop?
在我的应用程序中,我有一个input
字段,如果用户输入一个特定的字符串(基本上是一个匹配正则表达式的字符串),则显示一个div
。
(简化的)HTML部分:
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<input type="text" ng-model="searchText"/>
<div>Hello</div>
<div ng-show="isValid(searchText)">World !</div>
</div>
</div>
和我的控制器:
function TodoCtrl($scope) {
var reg = /20'd{2}/g;
$scope.isValid = function(str) {
console.log('Is valid?');
return reg.test(str);
}
}
当用户输入年份(通过正则表达式验证)时,我得到以下错误:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["isValid(searchText); newVal: true; oldVal: false"],["isValid(searchText); newVal: false; oldVal: true"],["isValid(searchText); newVal: true; oldVal: false"],["isValid(searchText); newVal: false; oldVal: true"],["isValid(searchText); newVal: true; oldVal: false"]]
http://errors.angularjs.org/1.2.1/$rootScope/infdig?p0=10&p1=%5B%5B%22isVal…2isValid(searchText)%3B%20newVal%3A%20true%3B%20oldVal%3A%20false%22%5D%5D
at http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:78:12
at Scope.$digest (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11472:19)
at Scope.$apply (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11682:24)
at HTMLInputElement.listener (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:15653:13)
at http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:2562:10
at Array.forEach (native)
at forEach (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:300:11)
at HTMLInputElement.eventHandler (http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:2561:5)
这里是一个链接到JsFiddle: http://jsfiddle.net/U3pVM/6598/
我的代码有什么问题,如何改进?
是reg
末尾的g
。当您在同一字符串上测试相同的表达式时,第二次它会在第一次找到的内容之后进行搜索。因此,如果以"2001."开头,该函数将返回true,然后再次调用,搜索剩余的"。"并返回false。
这是另一个答案,解释了它是如何工作的。
您应该使用$watch
和作用域变量,而不是使用函数的返回值来决定是否显示该元素。
结果是这一行:
reg.test(str)
在str
中做了一个更改,这是对作用域变量的引用,这会触发另一个摘要,导致无限循环。编辑:这是由于正则表达式具有全局标志,如另一个答案中提到的。因此,结合angular的消化循环是如何工作的,导致了它。
$watch
的解决方案:
function TodoCtrl($scope) {
var reg = /20'd{2}/g;
var isValid = function(str) {
$scope.show = reg.test(str);
}
$scope.$watch('searchText',isValid);
}
小提琴
尝试将reg变量移到函数内部
function TodoCtrl($scope) {
$scope.isValid = function(str) {
var reg = /20'd{2}/g;
console.log('Is valid?');
return reg.test(str);
}
}
正如Karolis juodelkv在链接中指出的那样,regex存储最后一个有效位置,而g符号导致第二次调用为false。通过在函数内部局部移动变量,如果您仍然想使用g符号,则reg变量是一个新的引用。
Angular对该函数求值两次,以确保它不会改变,但在第二次调用时,它确实返回了false,然后是true,然后是false,以此类推。
相关文章:
- 如何在Javascript函数调用中循环变量
- 使用滚动溢出-x进行无限循环
- jQuery延迟了ajax调用的循环
- 从index.html调用函数,该函数无限循环
- 使用jQuery无限循环播放HTML页面幻灯片
- Grunt任务没有加载,获得无限循环
- MeteorJS使用流星调用和流星方法时的无限循环
- AngularJS内部的调用函数进入无限循环
- 在 Jquery 或 Javascript 中调用方法的无限循环的正确方法是什么?
- ng-禁用函数调用在 ng-repeat 下处于无限循环中
- 在UI路由器中调用子状态时触发了无限循环
- document.ready用angular.js以无限循环调用
- 为什么我的Angular函数在无限循环中被调用?
- Angular JS的http拦截器async调用无限循环
- 是否有一种方法来确定ajax调用是否在无限循环中执行
- 为什么为同一函数调用window.setTimeout不会引入无限循环
- 在ajaxOncomplete之后触发ajax调用会导致无限循环
- 在回调函数中调用 onSubmit 会导致无限循环
- 用Angular表达式绑定Ajax调用的无限循环
- 调用$watchCollection时的angular$digest无限循环