Ионная ошибка? ион-освежитель и ион-бесконечный свиток

Я нашел проблему совместимости, используя два упомянутых компонента в одном списке, мой HTML и JS код ниже: HTML:

    <ion-content ng-controller="homeCtrl">
    <ion-refresher on-refresh="loadNewContent()" pulling-text="LoadMore..." spinner="android"></ion-refresher>
    <div ng-repeat="item in items">

        <a href="#/detail" class="thumb"><img ng-src="{{pathUrl+item['path']}}" style="height: auto;width:100%;"></a>
    </div>
    <ion-infinite-scroll ng-if="hasMore" on-infinite="loadMoreContent()" spinner="spiral" distance="5" immediate-check="false"></ion-infinite-scroll>
</ion-content>

JavaScript:

JiCtrls.controller('homeCtrl', ['$scope', '$timeout', 'DbService', 'JsonService',
function ($scope, $timeout, DbService, JsonService) {
    $scope.items = [];
    $scope.hasMore = true;
    var run = false;
    loadData(0);
    //下拉更新
    $scope.loadNewContent = function () {
        loadData(2);
        // Stop the ion-refresher from spinning
        $scope.$broadcast("scroll.refreshComplete");
    };

    //上拉更新
    $scope.loadMoreContent = function () {
        loadData(1);
        $scope.$broadcast('scroll.infiniteScrollComplete');
    };




    function loadData(stateType) {
        if (!run) {
            run = true;
            if ($scope.sql == undefined) {
                $scope.sql = "select top 5 * from information ";
            }
            DbService.getData($scope.sql, '').success(function (data, status, headers, config) {
                var convertData = JsonService.convertData(data);
                if (stateType == 1 || stateType == 0) {
                    // $scope.items = $scope.items.concat(convertData);
                    for (var i = 0; i < convertData.length; i++) {
                        $scope.items.push(convertData[i]);
                    }

                }
                else {
                    for (var i = 0; i < convertData.length; i++) {
                        $scope.items.unshift(convertData[i]);
                    }

                }

                if (convertData == null || convertData.length <= 0) {
                    $scope.hasmore = false;
       ;
                }
                $timeout(function () {
                    run = false;
                }, 500);

            }).error(function (errorData, errorStatus, errorHeaders, errorConfig) {
                console.log(errorData);
            });
        }
    }
}

]);

В браузере Chrome и Iphone все нормально, но в части телефона Android есть большая проблема. Когда функция повторного запуска ионного обновления активирует функцию on-infinite="loadMoreContent()", она будет работать бесконечно долго. Так в чем проблема?

2 ответа

Решение

Попробуй поставить $scope.$broadcast("scroll.refreshComplete"); а также $scope.$broadcast('scroll.infiniteScrollComplete'); в DbService.getData(...).success() обратный вызов, не в функциях, вызванных on-infinite а также on-refresh,

Объяснение:

Когда пользователь прокручивает до конца экрана, $scope.loadMoreContent который зарегистрирован по-бесконечности срабатывает. Показывается вращающийся элемент, и ион-бесконечная прокрутка делает паузу, проверяя, достиг ли пользователь конца экрана, до $scope.$broadcast('scroll.infiniteScrollComplete'); транслируется, когда он прячет счетчик и возобновляет проверку.

Представьте, что в вашем коде задержка в сети составляет 3 с, в этот список не добавляется новый элемент. В результате внутренняя высота ion-content никогда не обновляется, поэтому проверка, определяющая, достиг ли пользователь конца экрана, всегда будет возвращать true. И вы эффективно предотвращаете ion-infinite-scroll от приостановки этой проверки путем трансляции scroll.infiniteScrollComplete момент по бесконечности срабатывает. Вот почему он будет обновляться до бесконечности.

Чтобы улучшить качество кода и предотвратить будущие проблемы, вам может потребоваться позвонить $scope.$apply в вашем DbService.getData().success() обратный вызов (в зависимости от реализации getData) и ручное уведомление ion-контента для изменения размера в обратном вызове.

PS 来自中国的Ionic开发者你好:-) 两个中国人讲英语真累啊


Обновить

Я сделал кодекс, который сочетает в себе оба ion-refresher а также ion-infinite-scrollЯ думаю, что это работает довольно хорошо.

http://codepen.io/KevinWang15/pen/xVQLPP

HTML

<html ng-app="ionicApp">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <title>ion-refresher + ion-infinite-scroll 2</title>

    <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
    <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>

  </head>
  <body ng-controller="MyCtrl">

    <ion-header-bar class="bar-positive">
      <h1 class="title">ion-refresher + ion-infinite-scroll 2</h1>
    </ion-header-bar>

    <ion-content delegate-handle="mainScroll">
      <ion-refresher on-refresh="doRefresh()">

      </ion-refresher>
      <ion-list>
        <ion-item ng-repeat="item in list">{{item}}</ion-item>
      </ion-list>

      <ion-infinite-scroll
        ng-if="hasMore"
        on-infinite="loadMore()"
        distance="1%">
      </ion-infinite-scroll>
    </ion-content>

  </body>
</html>

JS

angular.module('ionicApp', ['ionic'])

.controller('MyCtrl', function($scope, $timeout, $q, $ionicScrollDelegate) {
  /*
    list of items, used by ng-repeat
  */
  $scope.list = [];

  var itemOffset = 0,
    itemsPerPage = 5;

  /*
    used by ng-if on ion-infinite-scroll
  */
  $scope.hasMore = true;

  /*
    isRefreshing flag.
    When set to true, on data arrive
    it first empties the list 
    then appends new data to the list.
  */
  var isRefreshing = false;

  /* 
    introduce a custom dataFetcher instance
    so that the old fetch process can be aborted
    when the user refreshes the page.
  */
  var dataFetcher=null;

  /*
    returns a "dataFetcher" object
    with a promise and an abort() method

    when abort() is called, the promise will be rejected.
  */
  function fetchData(itemOffset, itemsPerPage) {
    var list = [];
    //isAborted flag
    var isAborted = false;
    var deferred = $q.defer();
    //simulate async response
    $timeout(function() {
      if (!isAborted) {
        //if not aborted

        //assume there are 22 items in all
        for (var i = itemOffset; i < itemOffset + itemsPerPage && i < 22; i++) {
          list.push("Item " + (i + 1) + "/22");
        }

        deferred.resolve(list);
      } else {
        //when aborted, reject, and don't append the out-dated new data to the list
        deferred.reject();
      }
    }, 1000);

    return {
      promise: deferred.promise,
      abort: function() {    
        //set isAborted flag to true so that the promise will be rejected, and no out-dated data will be appended to the list
        isAborted = true;
      }
    };
  }

  $scope.doRefresh = function() {
    //resets the flags and counters.
    $scope.hasMore = true;
    itemOffset = 0;
    isRefreshing = true;
    //aborts previous data fetcher
    if(!!dataFetcher) dataFetcher.abort();
    //triggers loadMore()
    $scope.loadMore();
  }

  $scope.loadMore = function() {

    //aborts previous data fetcher
    if(!!dataFetcher) dataFetcher.abort();

    //fetch new data
    dataFetcher=fetchData(itemOffset, itemsPerPage);

    dataFetcher.promise.then(function(list) {
      if (isRefreshing) {    
        //clear isRefreshing flag
        isRefreshing = false;
        //empty the list (delete old data) before appending new data to the end of the list.
        $scope.list.splice(0);
        //hide the spin
        $scope.$broadcast('scroll.refreshComplete');
      }

      //Check whether it has reached the end
      if (list.length < itemsPerPage) $scope.hasMore = false;

      //append new data to the list
      $scope.list = $scope.list.concat(list);

      //hides the spin
      $scope.$broadcast('scroll.infiniteScrollComplete');

      //notify ion-content to resize after inner height has changed.
      //so that it will trigger infinite scroll again if needed.
      $timeout(function(){
        $ionicScrollDelegate.$getByHandle('mainScroll').resize();
      });
    });

    //update itemOffset
    itemOffset += itemsPerPage;
  };

});

Правильный Javscript выглядит следующим образом:

JiCtrls.controller('homeCtrl', ['$scope', '$timeout', '$ionicScrollDelegate', 'DbService', 'JsonService',
function ($scope, $timeout, $ionicScrollDelegate, DbService, JsonService) {
    $scope.items = [];
    $scope.hasMore = true;
    loadData(0);
    //下拉更新
    $scope.loadNewContent = function () {
        loadData(2);
    };
    //上拉更新
    $scope.loadMoreContent = function () {
        loadData(1);
    };



    function loadData(stateType) {

        if ($scope.sql == undefined) {
            $scope.sql = "select top 5 * from information”;
        }
        DbService.getData($scope.sql, '').success(function (data, status, headers, config) {
            var convertData = JsonService.convertData(data);
            if (stateType == 0) {
                for (var i = 0; i < convertData.length; i++) {
                    $scope.items.push(convertData[i]);
                }

            }
            else if (stateType == 1) {
                // $scope.items = $scope.items.concat(convertData);
                for (var i = 0; i < convertData.length; i++) {
                    $scope.items.push(convertData[i]);
                }

                $timeout(function () {
                    $scope.$broadcast('scroll.infiniteScrollComplete');
                }, 500);

            }
            else {
                for (var i = 0; i < convertData.length; i++) {
                    $scope.items.unshift(convertData[i]);
                }
                // Stop the ion-refresher from spinning
                $timeout(function () {
                    $scope.$broadcast("scroll.refreshComplete");
                }, 500);

            }
            $ionicScrollDelegate.resize();
            if (convertData == null || convertData.length <= 0) {
                $scope.hasmore = false;
            }

        }).error(function (errorData, errorStatus, errorHeaders, errorConfig) {
            console.log(errorData);
        });

    }
}

]);

Другие вопросы по тегам