使用 md virtual repeat 实现无限滚动

使用 md virtual repeat 实现无限滚动

Flying
2016-12-28 / 0 评论 / 165 阅读 / 正在检测是否收录...

还在 jQuery 时代,就看到那种无限滚动按需加载效果,后来用 [ngInfiniteScroll(https://sroze.github.io/ngInfiniteScroll) 实现了一个。最近深度使用 material 时,发现框架自带的 md-virtual-repeat-container 结合 md-virtual-repeat 也能很好地实现无限滚动。

scroll-angular.svg

md-virtual-repeat-container

md-virtual-repeat-container 是 md-virtual-repeat 组件的滚动容器。它有以下属性:

  • md-top-index:将滚动容器顶部项索引绑定到 $scope。它可以读取和设置滚动位置;
  • md-orient-horizontal:确定容器是否应水平滚动 (默认为方向是垂直滚动);
  • md-auto-shrink:当该数值小于原始尺寸时, 容器将收缩以适合项目数量;
  • md-auto-shrink-min:`md-auto-shrink 将收缩到的最小项目数(默认值 : 0)。

md-virtual-repeat

md-virtual-repeat 替换 ng-repeat 只呈现足够的 html 元素来填充容器并在用户滚动时重用它们。它有以下属性:

  • md-item-size:重复元素的高度或宽度 (每个元素必须相同)。这是可选的。如果丢失, 则尝试从 DOM 读取大小, 但仍假定所有重复的节点具有相同的高度或宽度;
  • md-extra-name:为重复作用域上可以分配当前迭代项计算其他名称(用于 md-autocomplete 中);
  • md-on-demand:如果设置,将 md-virtual-repeat 参数视为可以获取行的对象而不是数组。此对象必须使用两个方法实现以下接口。
  • getItemAtIndex − function(index) [object]:尚未加载时该索引对应的项或 null(应在该情况下开始下载该项目)。
  • getLength − function() [number]:md-virtual-repeat-container 调整大小后的数据长度。理想情况下, 当计数已知时, 此方法应返回它。否则, 返回比当前加载的项更高的数字以生成无限滚动行为。

代码实现

angular
  .module('myApp', ['ngMaterial'])
  .controller('AppCtrl', function($timeout, $filter) {
    this.infiniteItems = {
      loaded: 0,
      toLoad: 0,
      items: [],
      getItemAtIndex: function(index) {
        if (index > this.loaded) {
          this.fetchMore(index);
          return null;
        }
        return this.items[index];
      },

      getLength: function() {
        return this.loaded + 5;
      },

      fetchMore: function(index) {
        if (this.toLoad < index) {
          this.toLoad += 20;
          $timeout(function() {
            var arr = [];
            for (var i = 1; i < 21; i++) {
              arr.push({
                name: 'file' + (i + this.loaded).toString(),
                size: 1000 + Math.ceil(1000 * Math.random()),
                createTime: new Date().getTime() - Math.ceil(3600000 * 24 * 30 * Math.random())
              });
            }
            this.items = this.items.concat(arr);
            this.loaded = this.toLoad;
          }.bind(this), 300);
        }
      }
    }
  })

本实例中,由于使用了 md-on-demand 属性,所以必须 getItemAtIndexgetLength 两个方法。其中 getLength 返回 this.loaded + 5,比当前加载的项更高,这样才能生成无限滚动行为。

参考示例

访问 codepen 查看示例代码及效果

为了演示方便我们用的异步模拟数据,我们在真实环境中应该是调用 Service 来实现。

10

评论 (0)

取消