Infinite scroll doesn't work in AngularJS when scrolling over ng-view

I use code like this to create an endless scroll effect in AngularJS. I tried to reorganize part of the code by moving the contents of the scrollable container (in this case, ul ) to a separate html file, and then use ng-view to load the content.

After that scope.$apply(attr.whenScrolled); has no effect. The loadMore() method is simply no longer called.

Did I change something in scope after moving ul content to a separate file and dynamically upload it?

Update: Here is the code:

 App.directive('whenScrolled', function() { return function(scope, element, attr) { var raw = element[0]; // binding on element doesn't work so this is a temp fix $(document).bind('scroll', function() { var scrollPercentage = (($(window).scrollTop() + $(window).height()) / $(document).height()) * 100; if(scrollPercentage > 75 && !scope.in_progress && !scope.is_reached_end) { console.log('test') scope.$apply(attr.whenScrolled); } }); }; 

});

 App.config(['$routeProvider', function($routeProvider){ $routeProvider.when('/', { templateUrl: 'views/offers.html', controller: 'OffersCntl' }); }]); 

View:

 <div class="tileContainer" ng-controller="OffersCntl"> <h2>Something very important :)</h2> <div id="tiles" class="tiles" when-scrolled="loadMore()"> <div ng-view></div> </div> </div> 

I have a rather thick controller that I donโ€™t want to post by mail. It basically has a scope.loadMore method.

+4
source share
2 answers

Use ng-include instead of ng-view .

http://jsfiddle.net/pvtpenguin/U7Bz9/540/

For example, in your opinion:

  <div class="tileContainer" ng-controller="OffersCntl"> <h2>Something very important :)</h2> <div id="tiles" class="tiles" when-scrolled="loadMore()"> <div ng-include src="'offer.html'"></div> </div> </div> 
+5
source

This directive uses a scroll offset to give the component elasticity, rather than restricting it to a fixed height:

 app.directive('whenScrolled', function($window, $timeout) { return { restrict: "A", link: function(scope, element, attr) { // bind the digest cycle to be triggered by the scroll event // when it exceeds a threshold angular.element($window).bind('scroll', function() { var supportPageOffset = window.pageXOffset !== undefined; var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat"); var scrollY = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop; var iScroll = element.prop('offsetTop') + element.prop('offsetHeight'); var iScrooling = scrollY + ( this.screen.height * 0.9 ); //console.log(iScrooling+'/'+iScroll); if ( iScrooling >= iScroll ) { angular.element($window)[0].requestAnimationFrame(function(){ // invoke the function passed into the 'whenScrolled' attribute scope.$apply(attr.whenScrolled); }) } }); } } }); 

Your HTML:

 <div class="tileContainer" ng-controller="OffersCntl"> <h2>Something very important :)</h2> <div id="tiles" class="tiles" when-scrolled="loadMore()"> <div ng-repeat="item in items"> {{ item.id }} </div> </div> </div> 

Controller, you can replace it with an Ajax request

 $scope.items = []; var counter = 0; $scope.loadMore = function() { for (var i = 0; i < 5; i++) { $scope.items.push({id: counter}); counter += 10; } }; $scope.loadMore(); 

If you need support for older browsers, you can add this function:

 //requestAnimationFrame for old browsers (function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); 
0
source

Source: https://habr.com/ru/post/1479822/


All Articles