导致无限摘要循环的指令
Directive causing infinite digest loop
以下指令导致无限摘要循环,我不确定原因。关于如何重新编写代码的任何想法?
谢谢!
.directive('fitHeight', ['$window', '$timeout', '$location', function ($window, $timeout, $location) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
scope.docHeight = $(document).height();
var setHeight = function (newVal) {
var diff = $('header').height();
if ($('body').hasClass('layout-horizontal')) diff += 112;
if ((newVal-diff)>element.outerHeight()) {
element.css('min-height', (newVal-diff)+'px');
} else {
element.css('min-height', $(window).height()-diff);
}
};
scope.$watch('docHeight', function (newVal, oldVal) {
setHeight(newVal);
});
$(window).on('resize', function () {
setHeight($(document).height());
});
var resetHeight = function () {
scope.docHeight = $(document).height();
$timeout(resetHeight, 1000);
}
$timeout(resetHeight , 1000);
}
};
你有一个无限循环调用 resetHeight 函数内部的 resetHeight 函数。无限 $digest 循环是该无限循环的副作用。
您的 $timeout(resetHeight, 1000)
导致了 Infinite $digest loop
。这是因为方法 resetHeight
正在改变变量 $scope.docHeight
并开始另一个 $timeout
循环,$timeout
触发 $scope.$apply()
。在内部 Angular 监视可能看起来或实际上是什么,并且无穷无尽 $digest loop
,如果发现这种情况,则会抛出异常。
我不得不做一些类似于你正在做的事情,我不会在 Window Resize
事件上做 Debouncing
逻辑。这是因为在调整 window 的大小时会触发该事件。您将需要 throttle
处理程序调用,这样您就不会 $digest loops
.
在我下面的示例中,我将 Lodash 用于我的去抖动逻辑。
http://plnkr.co/edit/vUHcgpveDvijGE6l1LXy?p=preview
angular.module('myApp', [])
.directive('fitHeight', ['$window', '$timeout', '$location', function ($window, $timeout, $location) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
function setHeight(newVal) {
var diff = $('header').height();
if ($('body').hasClass('layout-horizontal')) {
diff += 112;
}
if ((newVal - diff) > element.outerHeight()) {
element.css('min-height', (newVal - diff) + 'px');
console.log('if');
} else {
element.css('min-height', $(window).height() - diff);
console.log('else');
}
}
setHeight($(document).height());
var docHeight = $(document).height();
var heightCheck = function() {
if (docHeight != $(document).height()) {
docHeight = $(document).height();
setHeight(docHeight);
}
};
var lazyHeightCheck = _.debounce(heightCheck, 200);
$(window).on('resize', lazyHeightCheck);
element.on('$destroy', function() {
$(window).off('resize', lazyHeightCheck);
});
}
}
}]);
以下指令导致无限摘要循环,我不确定原因。关于如何重新编写代码的任何想法?
谢谢!
.directive('fitHeight', ['$window', '$timeout', '$location', function ($window, $timeout, $location) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
scope.docHeight = $(document).height();
var setHeight = function (newVal) {
var diff = $('header').height();
if ($('body').hasClass('layout-horizontal')) diff += 112;
if ((newVal-diff)>element.outerHeight()) {
element.css('min-height', (newVal-diff)+'px');
} else {
element.css('min-height', $(window).height()-diff);
}
};
scope.$watch('docHeight', function (newVal, oldVal) {
setHeight(newVal);
});
$(window).on('resize', function () {
setHeight($(document).height());
});
var resetHeight = function () {
scope.docHeight = $(document).height();
$timeout(resetHeight, 1000);
}
$timeout(resetHeight , 1000);
}
};
你有一个无限循环调用 resetHeight 函数内部的 resetHeight 函数。无限 $digest 循环是该无限循环的副作用。
您的 $timeout(resetHeight, 1000)
导致了 Infinite $digest loop
。这是因为方法 resetHeight
正在改变变量 $scope.docHeight
并开始另一个 $timeout
循环,$timeout
触发 $scope.$apply()
。在内部 Angular 监视可能看起来或实际上是什么,并且无穷无尽 $digest loop
,如果发现这种情况,则会抛出异常。
我不得不做一些类似于你正在做的事情,我不会在 Window Resize
事件上做 Debouncing
逻辑。这是因为在调整 window 的大小时会触发该事件。您将需要 throttle
处理程序调用,这样您就不会 $digest loops
.
在我下面的示例中,我将 Lodash 用于我的去抖动逻辑。
http://plnkr.co/edit/vUHcgpveDvijGE6l1LXy?p=preview
angular.module('myApp', [])
.directive('fitHeight', ['$window', '$timeout', '$location', function ($window, $timeout, $location) {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
function setHeight(newVal) {
var diff = $('header').height();
if ($('body').hasClass('layout-horizontal')) {
diff += 112;
}
if ((newVal - diff) > element.outerHeight()) {
element.css('min-height', (newVal - diff) + 'px');
console.log('if');
} else {
element.css('min-height', $(window).height() - diff);
console.log('else');
}
}
setHeight($(document).height());
var docHeight = $(document).height();
var heightCheck = function() {
if (docHeight != $(document).height()) {
docHeight = $(document).height();
setHeight(docHeight);
}
};
var lazyHeightCheck = _.debounce(heightCheck, 200);
$(window).on('resize', lazyHeightCheck);
element.on('$destroy', function() {
$(window).off('resize', lazyHeightCheck);
});
}
}
}]);