ngInfiniteScroll - loadMore() method gets called o

2019-03-10 23:59发布

Solution below on the comments.

Problem: My loadMore() method gets executed on every container's scroll.

Meaning: loadMore() gets executed on each mouse scroll of the parent container (infinite-scroll-parent="true")

Desired result: to get loadMore() execute only when infiniteScrollDistance meets its conditions, instead of any tinny scroll I do.

My code is highly inspired by the demo_basic & demo_async.

My app is a photos gallery. I load the photos by ajax call, and populate them into a thumbnail directive repeater. I disable ng-Infinite-Scroll on controller initialization, and enable it on callback success.

    <div class="thumbnails grid__item page--content">
            <div id="gallery" class="unstyled-list" 
                    infinite-scroll='loadMore()' 
                    infinite-scroll-disabled='album.busy' 
                    infinite-scroll-parent="true" 
                    infinite-scroll-immediate-check="false" 
                    infinite-scroll-distance='2'>
                    <my-photo-directive ng-repeat="photo in photos"></my-photo-directive>
            </div>
    </div>

My coffee code has no surprises. It's logic is unimportant, because if I place a simple console.log, the problem still occurs.....

    $scope.album.busy = true
    $scope.loadMore = ->
            $scope.$apply ->
                    $scope.album.busy = true
            console.log('loadMore() been executed here')

My thumbnail directive is the same. No surprises, moment last photos gets populated onto the repeater, I enable the component.

    app.directive 'myPhotoDirective', ['$window', ($window) ->
        return {} =
            ....
            link: (scope, element, attrs) ->
                if scope.$last
                    scope.album.busy = false

I got no idea what i'm missing or doing wrong. I hope someone will be here to help me.

Thank you.

7条回答
SAY GOODBYE
2楼-- · 2019-03-11 00:26

I have solved my problem.

One of foundation properties that NIS (ngInfiniteScroll) measure, are $containerand $elem

  1. $container is the parent of the scrolled elements Element.
  2. $elem is the Element that contain the scrolled elements.

Example

<$container> <!-- can be a div -->
    <$elem> <!-- can be a list -->
        <photo/>
        <photo/>
        <photo/>
        <photo/>
    </$elem>
</$container>

What NIS is trying to do, is to calculate on each mouse scroll, if enabled, the relation between these two elements, and check if $elem is taller than $container, and then scroll down or not. (it also check other properties like - distance, immediate-check & disabled).

So this relation between this two fundamental elements, is crucial for the understanding & debugging of NIS.

So my problem was exactly that - The $container and $elem were equal at their height.
I had fixed css height values (100%) on both elements (mainly cause I read in the documentation that I must pass height), and by mistake I fixed $elemwhich was totally wrong.

Secondly - infinite-scroll-distance can cause this to happen as well. If the value that you're setting is high (let's say 2), and your loadMore() method don't populate enough items, even if you disable runtime of the method, than you will get infinite loadmore() executions.

查看更多
不美不萌又怎样
3楼-- · 2019-03-11 00:30

Without a Plunker to see the actual code I'll direct you right to the ngInfiniteScroll FAQ:

Why is ngInfiniteScroll triggering my expression on every single scroll event?

The infiniteScroll directive uses the height of the element that it's attached to in order to determine how close to the bottom of the window it is. In some cases, the browser can report a height of 0, which causes this behavior. Usually, this is due to a container element that only contains floated children. The simplest way to fix this problem is to add a "spacer" element to the bottom of the container (something like <div style='clear: both;'></div>); see this StackOverflow question and its associated answers for more details.

查看更多
迷人小祖宗
4楼-- · 2019-03-11 00:30

This might seem obvious, but it evaded me for a day.

I followed the example shown in the image on the homepage of NIS:

enter image description here

The important part to notice is the scroll distance:

infinite-scroll-distance="3"

According to the documentation,

if the browser window is 1000 pixels tall and infinite-scroll-distance is set to 2, the infinite scroll expression will be evaluated when the bottom of the element is within 2000 pixels of the bottom of the browser window. Defaults to 0 (e.g. the expression will be evaluated when the bottom of the element crosses the bottom of the browser window).

During my development, I only had ~50 items displaying, and thought, albeit incorrectly, that NIS was firing infinitely. In fact, it was just trying to fill up ~4000 pixels.

TL;DR: Remove (or at least reduce) infinite-scroll-distance if you have it set.

查看更多
姐就是有狂的资本
5楼-- · 2019-03-11 00:31

I had similar problem, except that infinite scroll wouldn't even stop loading by the time I reached end of container (I used infinite-scroll-container option from v1.2). After long debug, I noticed that container height was float (634.245px for example), whereas internal element height was close to it, but int (635px for example) and it would trigger cycle over and over, because it thought that bottom limit was reached. The problem with ng-infinite-scroll is that its visual and it doesn't deal with actual data, so I had to check for returned data from backend and block it if results were empty (infinite-scroll-disabled related function).

查看更多
混吃等死
6楼-- · 2019-03-11 00:39

I figured out the html format should be somewhat like this for nginfinitescroll to work. The addition of a dummy outer div with fixed height solved my problem

<div style="height:500px;">
   <div  infinite-scroll="myPagingFunction()">
     <div  ng-repeat="x in images"></div>
   </div>
</div>

Hope it helps somebody.

查看更多
在下西门庆
7楼-- · 2019-03-11 00:46

Let me add my two cents, had exact same problem, different solution! I have been debugging ng-infinite-scroll all day. At one point, I realized that javascript reports $(window).height() == $(document).height() which makes no sense whatsoever.

I did a bit googling, and it happens when you're missing DOCTYPE: jquery $(window).height() is returning the document height

But, that was not enough! My DOCTYPE was eaten by browser, at one point. You can read further: Too big number of $(window).height() on wordpress

查看更多
登录 后发表回答