0

我发现使用同一列表中提到的两个组件存在兼容性问题,我的 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手机出现大问题。当ion-refresher触发on-refresh功能时,on-infinite="loadMoreContent()"函数会无限运行。那么,有什么问题呢?</p>

4

2 回答 2

1

尝试将$scope.$broadcast("scroll.refreshComplete");and$scope.$broadcast('scroll.infiniteScrollComplete');放入DbService.getData(...).success()回调中,而不是放入由on-infiniteand触发的函数中on-refresh

解释:

当用户滚动到屏幕末尾时,$scope.loadMoreContent会触发注册为 on-infinite。微调器显示,并且 ion-infinite-scroll 暂停检查用户是否已到达屏幕末尾,直到$scope.$broadcast('scroll.infiniteScrollComplete');广播,当它隐藏微调器并恢复检查时。

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

为了提高代码质量并防止将来出现问题,您可能需要$scope.$applyDbService.getData().success()回调中调用(取决于 getData 的实现)并手动通知 ion-content在回调中调整大小。

PS 来自中国的离子开发者你好 :-) 两个讲英语真累啊</p>


更新

我制作了一个结合了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;
  };

});
于 2016-05-01T15:26:49.220 回答
0

正确的 JavaScript 如下:</p>

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

    }
}

]);

于 2016-05-02T06:07:25.043 回答