2015-10-19 77 views
1

我已經定義了下面的指令它包裝如果這個指令在一個瀏覽器選項卡(A)上運行的UI引導

angular.module('my-module') 
    .directive('myPagination', ['$filter', '$window', function ($filter, $window) { 

    return { 
     restrict: 'EA', 
     scope: { 
     itemsPerPage: '=', 
     totalItems: '=', 
     page: '=' 
     }, 
     link: function (scope, element, attrs) { 
     scope.hiddenElement = true; 
     var totalMargin = 200, widthByElement = 41; 

     scope.getWindowDimensions = function() { 
      return { 
      'w': element.width() 
      }; 
     }; 

     scope.$watch(scope.getWindowDimensions, function (newWidth, oldWidth) { 
      // calculate how many page buttons fit in the pagination horizontal bar 
      scope.maxSize = parseInt($filter('number')((newWidth.w - totalMargin)/widthByElement, 0)); 
     }, true); 

     angular.element($window).bind('resize', function() { 
      // "$digest already in progress" thrown by the following line 
      scope.$apply(); 
     }); 

     }, 
     template: '<div class="text-center paginationSelfCare" ng-show="totalItems > itemsPerPage">' + 
     '<pagination ng-show="totalItems/itemsPerPage <= maxSize" total-items="totalItems" items-per-page="itemsPerPage" ng-model="page" max-size="maxSize" class="pagination pagination-sm" ></pagination>' + 
     '<pagination ng-show="totalItems/itemsPerPage > maxSize" total-items="totalItems" boundary-links="true" direction-links="true" previous-text="<" next-text=">" first-text="<<" last-text=">>" items-per-page="itemsPerPage" ng-model="page" max-size="maxSize" class="pagination pagination-sm" ></pagination>' + 
     '</div>' 
    }; 
    }]); 

提供的pagination指令,和我切換到不同的選項卡(B),然後當切換回A,I看到在瀏覽器控制檯以下錯誤:

Error: [$rootScope:inprog] $digest already in progress http://errors.angularjs.org/1.4.4/ $rootScope/inprog?p0=%24digest minErr/<@http://127.0.0.1:9000/bower_components/angular/angular.js:68:12 [email protected]http://127.0.0.1:9000/bower_components/angular/angular.js:16273:1 $RootScopeProvider/this.$gethttp://127.0.0.1:9000/bower_components/angular/angular.js:16014:11 .link/<@http://127.0.0.1:9000/scripts/directives/pagination.js:30:11

pagination.js的線30是上述

標有註釋的行
scope.$apply(); 

在撥打電話scope.$apply();以避免此問題之前,我可以檢查一下嗎?我正在運行Angular版本1.4.4

回答

4

您可以嘗試$socpe.$applyAsync()而不是$scope.$apply(),它永遠不會與當前正在運行的摘要循環發生衝突。

$apply on $scope直接運行時直接嘗試運行摘要循環。它不檢查是否正在進行摘要循環,並且運行摘要循環,則會拋出$digest already in progress

儘管您可以通過使用包裝代碼$timeout函數來解決此問題,但我寧願去$applyAsync方法scope

$timeout確實運行了digest週期,但在運行之前,它檢查是否正在進行摘要,然後運行將此循環調用放入隊列並在運行摘要週期完成後運行。

$applyAsync是運行摘要循環的性能明智改進版本,當您運行此方法時,它首先檢查是否有任何摘要循環正在運行。如果發現任何正在運行的摘要循環,則將該塊放置在該摘要循環中(這意味着您減少了一個摘要循環)。

Reference Link

+0

是否有一個原因,我不應該總是使用'$ scope。$ applyAsync()'而不是'$ scope。$ apply()'? – ivanhoe

0

你的手錶是很奇怪的。這是通常的方式:

angular.element($window).bind('resize', function() { 
    // There are a lot of resize events, we do not need to change smth on each 
    // Once per some time is ok. 
    if (attrs.lastResize) { 
     $timeout.cancel(attrs.lastResize) 
    } 

    attrs.lastResize = $timeout(function() { 
     // actual code like 
     // like scope.maxSize = calc(); 
    }, 75) 
}); 

你不需要在這裏適用,因爲你有$超時。