2015-04-02 2 views
0

Следующая директива вызывает бесконечный цикл дайджеста, и я не уверен, почему. любые идеи о том, как переработать код?Директива, вызывающая бесконечный цикл дайджеста

спасибо!

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

ответ

0

Ваш $timeout(resetHeight, 1000) вызывает Infinite $digest loop. Это связано с тем, что метод resetHeight меняет переменную $scope.docHeight и начинает цикл $timeout, $timeout триггеров $scope.$apply(). Внутренне Угловые часы для того, что может показаться, или на самом деле, и бесконечно $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); 
          }); 
         } 
        } 
       }]); 
+0

спасибо за код. однако при первой загрузке страницы повторного калибровки не происходит. – Marco

+0

@Marco Мне жаль, что я забыл сделать первый звонок, я исправил пример и добавил живой для вас тест. –

+0

спасибо, ты спас меня от массивной головной боли! :) – Marco

0

У вас есть бесконечный цикл, вызывающий функцию resetHeight внутри функции resetHeight. Бесконечный цикл $ digest является побочным эффектом этого бесконечного цикла.

Смежные вопросы