离子有一个Bug?离子清新和离子无限滚动

时间:2016-05-01 14:51:25

标签: ionic-framework compatibility infinite-scroll refresher

我在同一个列表中找到了两个提到的组件的兼容性问题,我的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-refresh功能时,on-infinite =“loadMoreContent()”函数将无限期运行。那么,问题是什么?

2 个答案:

答案 0 :(得分:1)

尝试将$scope.$broadcast("scroll.refreshComplete");$scope.$broadcast('scroll.infiniteScrollComplete');置于DbService.getData(...).success()回调中,而不是on-infiniteon-refresh触发的功能。

说明:

当用户滚动到屏幕的末尾时,会触发使用on-infinite注册的$scope.loadMoreContent。微调器显示,离子无限滚动暂停,检查用户是否已到达屏幕的末尾,直到广播$scope.$broadcast('scroll.infiniteScrollComplete');,隐藏微调器并重新开始检查。

在您的代码中,假设网络中有3秒延迟,没有新项目添加到该3s的列表中。因此,ion-content的内部高度永远不会更新,因此确定用户是否已到达屏幕末尾的检查将始终返回true。并且您有效地阻止ion-infinite-scroll通过广播scroll.infiniteScrollComplete来暂停此检查。这就是它无限期更新的原因。

为了提高代码质量并防止将来出现问题,您可能需要在$scope.$apply回调中调用DbService.getData().success()(取决于getData的实现)和回调中的manually notify ion-content to resize。< / p>

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

更新

我制作了一个将ion-refresherion-infinite-scroll结合起来的codepen,我认为它工作正常。

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;
  };

});

答案 1 :(得分:0)

正确的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);
        });

    }
}

]);