导致无限消化循环的指令

时间:2015-04-02 23:47:23

标签: angularjs angularjs-directive angular-digest

以下指令导致无限的摘要循环,我不知道为什么。关于如何重新编写代码的任何想法?

谢谢!

  .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);
  }
};

2 个答案:

答案 0 :(得分:0)

你有一个无限循环调用resetHeight函数中的resetHeight函数。无限$ digest周期是该无限循环的副作用。

答案 1 :(得分:0)

您的$timeout(resetHeight, 1000)导致Infinite $digest loop。这是因为方法resetHeight正在更改变量$scope.docHeight并开始另一个$timeout周期,$timeout触发$scope.$apply()。内部Angular手表可能看起来是,或者实际上是,并且是无尽的$digest loop,如果它发现这种情况会引发异常。

我必须做一些类似于你工作的事情,我将不会在Debouncing事件上做Window Resize逻辑。这是因为在调整窗口大小时会触发事件。您需要throttle处理程序调用,以便您不会$digest loops

在下面的例子中,我使用Lodash作为我的Debouncing逻辑。

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);
                            });
                        }
                    }
                }]);