What should I do if I want to show thousands of pages in a slide-box

Apparently, I can create a slide for each page.
But I am not sure about the performance.
I am thinking of the other way, that is,
I create three slides, and transite to some slide programatically with the right page content and animation.
In a word, the three slides make a slide-loop/slide-ring. Is this feasible?

Yes.
There are several examples around, this one works well:

1 Like

Yes, it works well with 200 pages.
After I add it up to 2000 pages, the browser just reports whether I want to stop the js.
So I think the performance would be an issue.
There should be a better way around.

You might get to fix this using collection-repeat… But I’m not entirely sure on how to fly this :wink: ng-repeat renders all pages, collection-repeat renders only the pages in view… So it should fix the problem you speak of… If you can get it to work that is :wink:

1 Like

I also thought about collection-repeat.
It is usually difficult to calculate the width/height for collection-repeat item, but my situation is easier.
So I will give it a try. :slight_smile:

I have been having memory limitation issues with my slides, so I reimplemented them using a circular buffer of three slides where the “one behind” is always re-rendered as you slide. This actually turned out to work quite well and uses a lot less memory, and can support any number of objects.

I am quite curious about how you make the circular-buffer with the animation(slide-in-left/right).
Would you please share the main code with me? :slight_smile:

Nothing special in the code. Here are some relevant bits. I realize there are more efficient ways to code this but to me it’s more important that the code is easy to follow for all cases :wink:

<ion-view>
    <ion-slide-box does-continue="true" show-pager="false" on-slide-changed="slideChanged($index)">
        <ion-slide ng-repeat="single in data.singles track by $index">
            <ion-content>
                <div class="padding">
                         ....
                </div>
            </ion-content>
        </ion-slide>
    </ion-slide-box>
</ion-view>


app.config( function( $stateProvider, $urlRouterProvider ) {
   $stateProvider
...
      .state( 'app.single', {
         url: "/single/:index?newObject",
         views: {
            'tab-search': {
               templateUrl: "templates/single.html",
               controller: 'SingleCtrl'
            }
         }
      } )

.controller( 'SingleCtrl', ... {

      var countBostad;
      var curIndex = parseInt( $params.index );
      var lastIndex;
      var lastSlide;

      var loadSingles = function( index ) {
         var previndex = index - 1;
         var nextindex = index + 1;
         if( previndex < 0 ) previndex = countBostad - 1;
         if( nextindex >= countBostad ) nextindex = 0;
         $scope.data.singles[ 0 ] = $scope.data.bostad[ previndex ];
         $scope.data.singles[ 1 ] = $scope.data.bostad[ index ];
         $scope.data.singles[ 2 ] = $scope.data.bostad[ nextindex ];
         console.log( "loadSingles: " + previndex + " " + index + " " + nextindex + " of " + countBostad );
      }

      $scope.slideChanged = function( toSlide ) {
         if( toSlide == lastSlide ) return;
         console.log( " > slideChanged " + lastSlide + " > " + toSlide );
         var slideToLoad;
         var loadIndex;
         switch( lastSlide + ">" + toSlide ) {
            case "0>1":
            {
               slideToLoad = 2;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "1>2":
            {
               slideToLoad = 0;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "2>0":
            {
               slideToLoad = 1;
               curIndex = curIndex + 1;
               loadIndex = lastIndex + 2;
               break;
            }
            case "0>2":
            {
               slideToLoad = 1;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
            case "1>0":
            {
               slideToLoad = 2;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
            case "2>1":
            {
               slideToLoad = 0;
               curIndex = curIndex - 1;
               loadIndex = lastIndex - 2;
               break;
            }
         }

         if( curIndex < 0 ) curIndex = countBostad - 1;
         if( curIndex > countBostad ) curIndex = 0;

         if( loadIndex < 0 ) loadIndex = countBostad + loadIndex;
         if( loadIndex > countBostad ) loadIndex = loadIndex - countBostad;

         console.log( "   reload " + slideToLoad + " with " + loadIndex );

         $scope.data.singles[ slideToLoad ] = $scope.data.bostad[ loadIndex ];
         lastSlide = toSlide;
         lastIndex = curIndex;
      }

   } ] )

I cannot see much differences between the code and your last codepen example.
What is in your SingleCtrl to make the circular buffer?

Then you need to open your eyes, man!

The Codepen uses one slide per collection element and only renders three of them into the DOM.
So if you have 1000 elements you will have 997 empty slides and 3 populated slides in your DOM.

The code above uses a total of 3 slides ($scope.data.singles) independently of collection size, and keeps their content “centered” on the curIndex element, as if the three slides where connected in a triangle (=circular buffer).
So if you have 1000 elements you will still have only 3 slides in your DOM.

The loadSingles() function does the initial load of the 3 slides when the view is entered.
The slideChanged() function does the updating when the user slides, re-populating the slide that was “left behind” with the on that will be entered if the user continues to swipe in the same direction.

Got it. Thank you! :slight_smile:

You can try this too:

7 Likes

That is exactly what I want. Thanks a lot!

This is great @zarko. I am going to try and apply this to my usage now. Just curious, what does nr stand for?

nr for “number”. It’s basically a dynamically generated numeric value for every slide so that we know in which direction we are sliding / which slide content needs to be shown.

1 Like

@zarko I got it working! In my case I dont have an infinite amount of slides but its a large set and I still like your implementation as an optimization. Imagine this. I have 50 slides (and I have all the data for them on controller load). I jump in to the slidebox at 30 and load 29,30,31 as my defaults and then when it hits the make slide, i just find the appropriate data and load it in. Brilliant!

The only thing Im struggling with and trying to figure out is how to set some upper/lower limits. Mainly how to set does-continue to false when you hit a certain slide. For example, in your example, say you wanted the carousel to not scroll any further than -5 or +6.

UPDATE: So I was able to prevent scrolling by using $ionicSlideBoxDelegate.$getByHandle('slideshow-slidebox')._instances[0].loop(false); if im on the first or last slide but the trickier part is when you arrive at the slide it has to be the head (if its your lower bound) or the tail (if its your higher bound). This is more difficult than I anticipated.

good to hear you had some progress. perhaps i or anyone wanting can soon create the ultimate component / ion that does all this magic.

That would be the ultimate slider @zarko and solve a lot of performance issues for a lot of people. I’ll keep stabbing at it but I have kind of hit a brick wall at the moment. The fact that it has to end on the tail (or the lower limit has to end up as the head) has really stumped me.

Hi guys,

I’ve implemented a similar version of the circular buffer for the slider but I’m stuck at one point.
Basically I want to implement the circular slider but with a start and end, as in, it would prevent sliding from the first image of the array to the last image…

I’ve tried changing the does-continue to false when it reaches the last/first image of the gallery but it doesn’t seem to work (Even if triggering the update method of the delegate)

Any thoughts ?

Any progress here? @zarko @travisdahl
Im currently trying to achieve the exact same thing.

I have a certain amount of slides, lets say 100. I want to start at the first one and automatically fill the other two slides with the next ones out of these 100, so the user has the feeling of an endless scrolling. When it comes to slide 100, scrolling in the right direction should stop, only a backwards scrolling/sliding is then possible.

Same thing in the other direction, but if the user hits slide 0, no more scrolling in left direction should be possible…any help would be appreciated!