6

I want to render many(about 1000) components and I am displaying them through aura:iteration in another aura:iteration. This is causing me performance issues. I want to display only 10 records at an instance, and on scroll of mouse, load next 10 and so on...It should be like the way feed is loaded on a FB page or chatter. Any ideas how can this be implemented?

markup:

<aura:iteration var="outerListElement" items="{!v.listOfLists}">
   <tr>
      <aura:iteration var="singleEntry" items="{outerList">
       <td >
           <div class="slds-truncate">
               <c:newComponent singleEntry="{!singleEntry}" outerListElement="{!outerListElement}" attr1="{!v.attr1OfParent}">
           </div> 
       </td>
      </aura:iteration>
   </tr>
</aura:iteration>
15

You could implement infinite scrolling similar to what I did for my custom Lightning Component that renders data table.

In your main component's render.js file attach a listener to the window.onscroll event. As the user scrolls down the page the below code detects once the user has neared the bottom then can take action. In my example, I invoke helper.getNextPage( component );

For your purposes, you might start with {!v.listOfLists} holding only 10 elements to start with, and then as the user scrolls you append more elements to the list.

Note, the below solution stores the JavaScript interval id in v.setIntervalId attribute of the component so that the polling can be stopped when the component is unrendered / destroyed.

({
    afterRender : function( component, helper ) {

        this.superAfterRender();

        // this is done in renderer because we don't get
        // access to the window element in the helper js.

        // per John Resig, we should not take action on every scroll event
        // as that has poor performance but rather we should take action periodically.
        // http://ejohn.org/blog/learning-from-twitter/

        var didScroll = false;

        window.onscroll = function() {
            didScroll = true;
        };

        // periodically attach the scroll event listener
        // so that we aren't taking action for all events
        var idOfSetInterval = window.setInterval( $A.getCallback( function() {

            // Since setInterval happens outside the component's lifecycle
            // We need to check if component exist, only then logic needs to be processed
            if ( didScroll && component.isValid() ) {

                didScroll = false;

                // adapted from stackoverflow to detect when user has scrolled sufficiently to end of document
                // http://stackoverflow.com/questions/4841585/alternatives-to-jquery-endless-scrolling
                if ( window['scrollY'] >= document.body['scrollHeight'] - window['outerHeight'] - 100 ) {
                    helper.getNextPage( component );
                }

            }

        }), 1000 );

        // Save the id.We need to use in unrender to remove the setInterval()
        component.set( "v.setIntervalId", idOfSetInterval );
    },

    unrender: function( component, helper ) {

        this.superUnrender();

        // Since setInterval() will be called even after component is destroyed
        // we need to remove it in the unrender
        window.clearInterval( component.get( "v.setIntervalId" ) );
    }
})
  • 3
    I have updated the answer with code to 1) check for component valid before the calling the getNextPage() since setInterval() is async. 2) To Remove the same in the unrender, since scope of setInterval() is different from the component's. – Praveen Dec 22 '16 at 14:14
  • @Doug Ayers : Thanks for you solution I am using it extensively. I had a problem in it though that renderer is catching horizontal scroll as well and executes helper.getNextPage in above code. This behaviour is happening in salesforce classic and salesforce service console and not in one.app. Do you have any clue about why this could be happening? – Sarang Jan 31 '17 at 4:55
  • I made it work. Edited the code with same. – Sarang Feb 1 '17 at 7:12
  • Does this still work? I'm am having trouble getting the event to fire. – Caspar Harmer May 20 '19 at 4:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.