如何使用md-virtual-repeat在两个方向上进行无限滚动?

Chr*_*eek 7 infinite-scroll angularjs angularjs-ng-repeat angularjs-material

使用md-virtual-repeat实现了无限水平滚动.当我向右滚动时,每次需要时它会获取25条记录.

<md-virtual-repeat-container flex md-orient-horizontal>
  <div md-virtual-repeat="item in $ctrl.infiniteItems" md-on-demand>
    {{ item.date }}
  </div>
</md-virtual-repeat-container>
Run Code Online (Sandbox Code Playgroud)

基本上它是一个水平的日期列表(包含其他信息),您可以滚动.滚动到将来的日期.工作良好.

现在,我想滚动到过去日期的左侧.

我正在寻找一种从中间开始的方式(今天的日期是).我已尝试md-top-index通过控制器上的值进行设置,但在从服务器获取第一页后,它会重置为较低的数字.

<md-virtual-repeat-container flex md-orient-horizontal md-top-index="$ctrl.topIndex">
  <div md-virtual-repeat="item in $ctrl.infiniteItems" md-on-demand>
    {{ item.date }}
  </div>
</md-virtual-repeat-container>
Run Code Online (Sandbox Code Playgroud)

如何配置md-virtual-repeat-containermd-virtual-repeat允许向左和向右滚动?

更新:这是一个带有Codepen的沙箱,我希望能够容纳一个向左滚动的按钮.https://codepen.io/christiaanwesterbeek/pen/pLRQgg

Update2:设置md-top-index为某个正整数允许在两个方向上滚动.但是在角材料部位给出的例子md-top-index不是无限滚动.我的问题的解决方案是md-top-index无限滚动的地方.

Tak*_*aki 0

好吧..回答你的问题:

您可以通过将文档body的标签更改为来允许以 md-virtual-repeat 的相反方向滚动html<body dir="rtl">

快速概述:

我到处找这个,但我找不到任何东西,我想你也找到了,所以我angular-material.js从本地的Angular CDN下载,看看他们如何处理这个问题,这是一个片段:

VirtualRepeatContainerController.prototype.handleScroll_ = function() {
  var ltr = document.dir != 'rtl' && document.body.dir != 'rtl';
  if(!ltr && !this.maxSize) {
    this.scroller.scrollLeft = this.scrollSize;
    this.maxSize = this.scroller.scrollLeft;
  }
  var offset = this.isHorizontal() ?
      (ltr?this.scroller.scrollLeft : this.maxSize - this.scroller.scrollLeft)
      : this.scroller.scrollTop;

  if (offset === this.scrollOffset || offset > this.scrollSize - this.size) return;

  var itemSize = this.repeater.getItemSize();
  if (!itemSize) return;

  var numItems = Math.max(0, Math.floor(offset / itemSize) - NUM_EXTRA);

  var transform = (this.isHorizontal() ? 'translateX(' : 'translateY(') +
      (!this.isHorizontal() || ltr ? (numItems * itemSize) : - (numItems * itemSize))  + 'px)';

  this.scrollOffset = offset;
  this.offsetter.style.webkitTransform = transform;
  this.offsetter.style.transform = transform;

  if (this.bindTopIndex) {
    var topIndex = Math.floor(offset / itemSize);
    if (topIndex !== this.topIndex && topIndex < this.repeater.getItemCount()) {
      this.topIndex = topIndex;
      this.bindTopIndex.assign(this.$scope, topIndex);
      if (!this.$rootScope.$$phase) this.$scope.$digest();
    }
  }

  this.repeater.containerUpdated();
};
Run Code Online (Sandbox Code Playgroud)

这就是我发现它们依赖于主体的方向来引导无限滚动的原因,因此如果您不想更改文档的方向,则html必须下载它,编辑此部分并使用它而不是cdn,但是..它不会按预期工作;

在正常情况下,从左向右滚动将增加变量this.scrollLeft,正如您在代码片段中看到的那样,它随处可见,它将增加 和 ,offset并且translateX()所有内容都会落入正确的位置,

但如果您从右向左滚动,该handleScroll_函数会将 设定this.scrollOfsset为视图的宽度,当您向左滚动时,该宽度this.scrollLeft将减少而不是增加,一旦您到达前 25 个末尾,所有内容都会分开,

我尝试了console.log里面的所有变量,并将其rtl与进行比较ltr,以查看何时何地发生故障,我尝试使用这些值和操作,但没有成功,请随意做同样的事情并进行实验,也许我错过了一些东西(但是嘿,问题只是改变方向,对吧?:P)

我建议你去尝试别的东西(比如上面评论中的那些)

我希望这对您有所帮助,或者至少给您一个想法,祝​​您好运。

编辑 :

因为这取决于 的body方向,所以您可以向左或向右滚动,而不是两者都滚动,即使您设置md-top-index并从中间开始( with dir="ltr"),您也只能在一侧(向右)无限滚动,如果您返回,它只是显示旧的已加载数据,

您可以查看文件VirtualRepeatController.prototype.virtualRepeatUpdate_内部js,了解它如何添加新块并更新索引和滚动。

旁注:人们希望它用于反向垂直滚动(用于聊天应用程序),并且存在未解决的问题,但由于他们转向了 Angular 2.x 及更高版本,因此不太可能添加它

底线是:如果您想仅通过配置在两侧滚动,恐怕您不能,如果您绝对想要这个,您将不得不进行修改angular-material.js以满足您的需求。