I have an angular scope containing two things:
Depending on how far you have scrolled down the page/table, I have to update one of the small info bits in the header; you can think of it as a % counter how far you've scrolled.
To get the current scroll position, I have written a directive (you can also find it here):
app.directive "setWindowScroll", ->
restrict: "E"
scope:
setVariable: "="
link: (scope) ->
$(window).scroll ->
scope.$apply ->
scope.setVariable = $(window).scrollTop()
My problem is that this makes scrolling around in the table u*nsuably slow*. This is because the veriable I write to with my directive is in the extra-info in the scope, and changing that seems to cause angular to dirty-check the whole table for changes when my $apply
is called.
I know that this scrolling will never change anything in my table, and would like to restrict my $apply
to affect the header part of my site.
How can I make angular not dirty check the table?
Angular does the dirty checking under a process called digest. When you do a call to $scope.$digest()
it will propagate to every child scope of $scope
. To notify angular about changes you usually do a $scope.$apply()
. At the end of the $apply() angular does a digest on the root scope, which triggers a diggest on every scope in your application. So to avoid the digest on in your scope with the big table scope, you should make sure that it is not the child of the extra information scope, and rather than doing an $scope.$apply() in your directive you could do a $scope.$digest(). This might be a bit confusing so I've made a plunker that tries to show the difference. Open your console and see the difference in the scroll event and button click:
http://plnkr.co/edit/45gKhAIt0DrozS7f0Bz2?p=preview
// this will only cause a digest in the current scope and its children
angular.element($window).bind('scroll',function(){
$scope.scrollY = $window.scrollY;
$scope.$digest();
})
// this will cause a digest in every scope
angular.element($window).bind('scroll',function(){
$scope.scrollY = $window.scrollY;
$scope.$apply();
})
When all this is said, it's a very unusual thing to do - and probably not a good idea for a number of reasons (angular doesnt scale well with thousands of elements, you can't use any of the angular event directives (ngClick etc) because they're all wrapped in $apply) - but if you can't render the table on the server side you can give this a try.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With