Ionic (angularjs) ion-slide-box with ng-repeat not

2019-01-12 01:18发布

问题:

I have an ion-slide-box using ng-repeat showing images that are fetched from a remote server.

    <ion-slide-box on-slide-changed="slideChanged(index)" auto-play="true" does-continue="true">
      <ion-slide ng-repeat="slide in files">
        <img ng-src="{{slide.filename}}" > 
      </ion-slide>
    </ion-slide-box>

and the js:

  $scope.getFiles = function() {
     Files.query({  
        //some parameters

     }).$promise.then(function(data) {
        $scope.files = data;
  });

When getFiles() is called (which fires a service that is not shown here), $scope.files is updated successfully. But the DOM (the images loaded into the ion-slide-box) are not automatically updated. How do I refresh the DOM?? I have tried timeout (nothing happens) and $scope.$apply (throws error that $dispatch already sterted.)

Even though this is a mobile app, when testing in desktop browser, I can re-size the browser and the images automatically display. So either I figure out how to keep this updated, or find a better image slider/carousel to use.

回答1:

You need to wait the ng-repeat is rendered before being able to update() your slidebox, use this directive :

angular.module('starter')
 .directive('repeatDone', function () {
   return function (scope, element, attrs) {
     if (scope.$last) { // all are rendered
       scope.$eval(attrs.repeatDone);
     }
   }
})

HTML :

<ion-slide-box>
  <ion-slide ng-repeat="day in week" repeat-done="repeatDone()" >

In your controller

$scope.getFiles = function() {
 Files.query({  
    //some parameters

 }).$promise.then(function(data) {
    $scope.week = data;
});

$scope.repeatDone = function() {
  $ionicSlideBoxDelegate.update();
  //$ionicSlideBoxDelegate.slide($scope.week.length - 1, 1);
};


回答2:

You need to call the $ionicSlideBoxDelegate.update() method after you have changed the scope variable. The slidebox does not automatically listen for changes in the latest version of the framework.

http://ionicframework.com/docs/nightly/api/service/$ionicSlideBoxDelegate/

You should set a delegate-handle attribute and use that to make sure you don't interfere with any other slideboxes you make have loaded at the time.

html

<ion-slide-box delegate-handle="image-viewer" on-slide-changed="slideChanged(index)" auto-play="true" does-continue="true">
  <ion-slide ng-repeat="slide in files">
    <img ng-src="{{slide.filename}}" > 
  </ion-slide>
</ion-slide-box>

js

$scope.getFiles = function() {
  Files.query({  
  //some parameters

  }).$promise.then(function(data) {
    $scope.files = data;
    $ionicSlideBoxDelegate.$getByHandle('image-viewer').update();
  });
}

I believe this will change in the near future so your code will work as expected. They are working on an updated slidebox component but it was pulled at the last minute to speed up the latest release.



回答3:

To work properly must do the following . After 8 hours of testing and achieve internet search to find the right solution.

<ion-slide-box on-slide-changed="slideChanged(index)" auto-play="true" does-continue="true">
          <ion-slide ng-repeat="slide in files">
            <img ng-src="{{slide.filename}}" > 
          </ion-slide>
</ion-slide-box>

delegate-handle="image-viewer" does not have to be in ion-slide-box must be in <ion-content delegate-handle="mainhanddle"> and from the controller must execute these two commands:

$ionicSlideBoxDelegate.update();
$ionicSlideBoxDelegate.$getByHandle('mainhanddle').update();

At the end of each call.

To add this here, <ion-slide-box delegate-handle="image-viewer" other important properties such as cancel and for example nr-repeat does not work properly.

Well, I hope I have helped , if you need more details please do not hesitate to contact me.



回答4:

Instead of:

$scope.files = data;

Try:

$scope.files.splice(0,$scope.files.length);
$scope.files = $scope.files.concat(data);

That should allow you to update the content of the array without losing the initial memory reference.

Note: I am assuming that $scope.files and data are arrays.



回答5:

I achieved to resolve this trouble using the library ion-image-lazy-load. Try out with this approach:

JS:

.controller('myCtrl', function ($scope) {
  $scope.images = imagesArray(); // Get array of objects with image urls
  $scope.slider = {
    options: {
     direction: 'horizontal',
     slidesPerView: '1',
     grabCursor: true
    }
  };
});

View:

<ion-content lazy-scroll>
   <ion-slide-box style="width:100% !important">
       <ion-slide ng-repeat="slide in images">
           <img image-lazy-src="{{slide.url}}" lazy-scroll-resize="true" image-lazy-loader="lines" style="width:100%">
       </ion-slide>
    </ion-slide-box>
</ion-content>