Slides generated with ng-repeat causing issues (slide-box)

The first time I try to populate a slide-box using ng-repeats the slidebox pager doesn’t show when the page is loaded, when trying to debug on chrome (desktop) and open the inspector, the slidebox gets fixed automatically.

Is there a way to force a reload of the slide-box after page load?

Bernard.

6 Likes

Maybe there could be an error with .slider, .slider-slides and .slider-slide elements’ widths.
When I try to insert a slide-box in a modal, those widths became 0px: here’s an example.

Could you try to check if .slider width is equal to 0?
Thanks

2 Likes

Yes, width is 0 at the start, then when the chrome inspector pops up the value changes and everything gets fixed.

Well, yesterday I posted the issue on GitHub (#360).
Thanks :slight_smile:

I get this too, creating some slides from content loaded with $http, content appears only when window is resized.

I will add a comment to your github issue.

I found a temporar fix for it. I added a custom directive near to the ng-repeat that watches the loop, and when it gets to the final element, I trigger an event, slider.reload, that I added to the slide-box directive from ionic-angular that simply calls slider.load() again.
I wonder if there’s another way less intrusive of doing this.

@cata_rock can you please post directive code here. I am having the same issue but i am new to angular. Any help would be appreciated.

I found the solution use $ionicSlideBoxDelegate service and call $ionicSlideBoxDelegate.update();

.controller('MyPhotosCtrl', function ($scope, $ionicSlideBoxDelegate) {
  $scope.photos= [ ... ]
   $ionicSlideBoxDelegate.update();
})

<slide-box show-pager="false" on-slide-changed="onSlideChanged(index)" active-slide="currentIndex">
       <slide ng-repeat="photo in photos">
             <img ng-src="{{ photo.ThumbnailURL }}" />
        </slide>
</slide-box>
29 Likes

I have implemented card list and each card item has slide (implemented through hg-repeat). $ionicSlideBoxDelegate.update(); works for the first slide but doesn’t work for other slides.

   <div class="list card" data-ng-repeat="(key, item) in items">

        <div class="item item-button-right item-text-wrap">
            <h2>{{item.name}}</h2>

            <p class="subdued">
                {{photoCount}} Photo
            </p>
        </div>

        <div class="item item-body" style="height:250px">

            <ion-slide-box show-pager="true">
                <ion-slide ng-repeat="photo in photos[key]">
                    <img ng-src="{{ photo.name }}"/>
                </ion-slide>
            </ion-slide-box>

        </div>

When are you calling the $ionicSlideBoxDelegate.update(); ? I’m just guessing here, but if you are setting $scope.items and then immediately calling the update, it’s possible the views aren’t rendered yet. So, the update applies before all the views are rendered.

Perhaps you can delay the update with a timeout - say 500ms. Then, see if that helped?

I am calling after $scope.items and $scope.photos are loaded with data. I thought the same and even tried updating after 4 second delay but that didn’t work either.

Can you setup a CodePen or Plunker sample?

See this sample of dynamically adding slides:

Nightly as of 03/18/2014 : http://codepen.io/calendee/pen/CxvFl/

0.9.27 : http://codepen.io/calendee/pen/eCgrs/

update() is not working for me on iOS simulator and device.

I’m using this in my template:

  <ion-slide ng-repeat="artist in random_artists">
    <div class="box">
            {{artist.title}}
    </div>
  </ion-slide>

And this in my controller:

.controller('HomeCtrl', function($scope, $stateParams, $ionicSlideBoxDelegate, DataHandler) {
$scope.random_artists = DataHandler.GetRandomArtists(3);
  setTimeout(function(){
      $ionicSlideBoxDelegate.update();
  },5000);
}

In the browser the slidebox is immediately populated with the scope variable. But on device it doesn’t, unless you navigate to another state and navigate back again. Then the slidebox is filled up. $ionicSlideBoxDelegate.update(); doesn’t seem to do anything, regardless of timeout length.

Any ideas?

3 Likes

Wild guess here, but I need you to try it. You are not using “dot notation”. I think when the slides are first setup, you are only binding to a primitive. When you update the artists, that does not get detected by the view because it was a COPY, not a reference to your artist list.

Please change to this:

<ion-slide ng-repeat="artist in data.random_artists">
<div class="box">
        {{artist.title}}
</div>
</ion-slide>
.controller('HomeCtrl', function($scope, $stateParams, $ionicSlideBoxDelegate, DataHandler) {
$scope.data.random_artists = DataHandler.GetRandomArtists(3);
  setTimeout(function(){
      $ionicSlideBoxDelegate.update();
  },5000);
}
1 Like

@Calendee Unfortunately that doesn’t work and breaks Angular from initializing on browser and device.

Error message is TypeError: Cannot set property 'random_artists' of undefined.

When I wrap the getting of the scope variable in a separate timeout from the slideboxDelegate update function, like:

  setTimeout(function(){
    $scope.random_artists = DataHandler.GetRandomArtists(3);
  },2000);

 setTimeout(function(){
      $ionicSlideBoxDelegate.update();
  },5000);

the slidebox never loads any slides from the scope variable, even after switching to another state. This happens on browser, simulator and device.

My code had a small bug there. Do this in the controller:

.controller('HomeCtrl', function($scope, $stateParams, $ionicSlideBoxDelegate, DataHandler) {

$scope.data = {};

$scope.data.random_artists = DataHandler.GetRandomArtists(3);
  setTimeout(function(){
      $ionicSlideBoxDelegate.update();
  },5000);
}

General rule of thumb is to NOT use setTimeout with Angular. It occurs outside Angular’s digest cycle and so Angular does not know there is something to update. Any asynchronous code not wrapped in Angular digest cycle will have this same problem. Use $timeout instead. However, you should not need it at all for this problem.

1 Like

Just tested this; no more undefined error but no effect on the slidebox either.
Problem remains as before: on browser the slides are immediately populated, on simulator the slides are only populated after switching to another state and going back.

Using 0.9.27 btw.

I’ve tried using this with a setTimeout of 5 seconds (even though I understand your point about the Angular digest cycle), and without. No difference. :frowning:

Ugh… How about trying ng-cloak. The phone’s CPU is much slower than the desktop; so maybe all this needs to be hidden from the view until all is rendered.

No difference, I’m afraid. Might be good to note that I’m using multiple slides in the slidebox, one which is static, the others are generated by ng-repeat. Like so:

<ion-slide-box class="center" auto-play="true" does-continue="true">
  <ion-slide ng-if="FestivalInProgress == false">
    <div class="box">
    <!-- content goes here -->
    </div>
  </ion-slide>
  <ion-slide ng-repeat="artist in data.random_artists" ng-if="FestivalInProgress == false && $index < 3" ng-cloak>
    <div class="box">
    <!-- content goes here -->
    </div>
  </ion-slide>
 </ion-slide-box>

I’m thinking this might have something to do with the fact that my dataloader might not have completed it’s preparation of the data before the screen that uses this slidebox is displayed (I’m using this on the home screen of the app so it’s immediately on startup). After moving to another state and going back, the slidebox does seem to fill, so maybe the data preparation functions have finished by then.

Going to look into ionicLoader for this.
Thanks @Calendee! If you have any other ideas I’d love to hear them.