为什么在 ng-if 中使用 .match 似乎会导致摘要循环
Why does using .match inside of an ng-if seem to cause digest cycles
考虑以下简单的 angularjs 应用程序(此处 fiddle:https://jsfiddle.net/jeconner/n3e61o0a/33/):
<div ng-controller="MyCtrl">
<div ng-if="showVal()">
{{val}}
</div>
</div>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope, $interval) {
$scope.val = 0;
$interval(function () {
$scope.val = Math.trunc(Math.random() * 200);
}, 1000);
$scope.showVal = function () {
//return $scope.val % 2 == 0; // This works!
return String($scope.val).match(/[1]{1}[0-9]{2}/); // Console errors!
};
}
val
的值设置为每秒更改一次。如果您取消注释 showVal
中的第一个 return 行,则运行时没有错误,显示 val
为偶数。
但是,如果您将 val
转换为字符串并针对上述正则表达式进行测试,则会出现控制台错误,抱怨已达到 10 个摘要周期:
"Error:
[$rootScope:infdig 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: ["showVal(); newVal:
[\"176\"]; oldVal:
[\"176\"]"],["showVal(); newVal:
[\"176\"]; oldVal:
[\"176\"]"],["showVal(); newVal:
[\"176\"]; oldVal:
[\"176\"]"],["showVal(); newVal:
[\"176\"]; oldVal:
[\"176\"]"],["showVal(); newVal:
[\"176\"]; oldVal: [\"176\"]"]
http://errors.angularjs.org/1.2.1/$rootScope/infdig?p0=10&p1=%5B%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%5D
at https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:78:12
at Scope.$digest (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11472:19)
at Scope.$apply (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11682:24)
at tick (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:8189:36)"]
"Script error."
为什么会出现这个错误?是否有在 ng-if 中使用正则表达式的正确方法来避免此错误?
我尽量不要像我的 ng-show 或 ng-if 那样拥有功能。他们被称为 non-stop,通常是不必要的。我发现使用幕后设置的布尔值在内存和性能方面要容易得多。例如,在您的代码中,它每秒设置 $scope.val
,但在摘要期间可能多次 运行 showVal() 函数。考虑这个替代方案,我在 fiddle 中测试它没有错误:
<div ng-controller="MyCtrl">
<div ng-if="showValBool">
{{val}}
</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $interval) {
$scope.val = 0;
$scope.showValBool = false
$interval(function () {
$scope.val = Math.trunc(Math.random() * 200);
$scope.showValBool = String($scope.val).match(/[1]{1}[0-9]{2}/);
}, 1000);
}
考虑以下简单的 angularjs 应用程序(此处 fiddle:https://jsfiddle.net/jeconner/n3e61o0a/33/):
<div ng-controller="MyCtrl">
<div ng-if="showVal()">
{{val}}
</div>
</div>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope, $interval) {
$scope.val = 0;
$interval(function () {
$scope.val = Math.trunc(Math.random() * 200);
}, 1000);
$scope.showVal = function () {
//return $scope.val % 2 == 0; // This works!
return String($scope.val).match(/[1]{1}[0-9]{2}/); // Console errors!
};
}
val
的值设置为每秒更改一次。如果您取消注释 showVal
中的第一个 return 行,则运行时没有错误,显示 val
为偶数。
但是,如果您将 val
转换为字符串并针对上述正则表达式进行测试,则会出现控制台错误,抱怨已达到 10 个摘要周期:
"Error: [$rootScope:infdig 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: ["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"] http://errors.angularjs.org/1.2.1/$rootScope/infdig?p0=10&p1=%5B%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%2C%5B%22showVal()%3B%20newVal%3A%20%5B%5C%22176%5C%22%5D%3B%20oldVal%3A%20%5B%5C%22176%5C%22%5D%22%5D%5D at https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:78:12 at Scope.$digest (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11472:19) at Scope.$apply (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11682:24) at tick (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:8189:36)"] "Script error."
为什么会出现这个错误?是否有在 ng-if 中使用正则表达式的正确方法来避免此错误?
我尽量不要像我的 ng-show 或 ng-if 那样拥有功能。他们被称为 non-stop,通常是不必要的。我发现使用幕后设置的布尔值在内存和性能方面要容易得多。例如,在您的代码中,它每秒设置 $scope.val
,但在摘要期间可能多次 运行 showVal() 函数。考虑这个替代方案,我在 fiddle 中测试它没有错误:
<div ng-controller="MyCtrl">
<div ng-if="showValBool">
{{val}}
</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $interval) {
$scope.val = 0;
$scope.showValBool = false
$interval(function () {
$scope.val = Math.trunc(Math.random() * 200);
$scope.showValBool = String($scope.val).match(/[1]{1}[0-9]{2}/);
}, 1000);
}