如何使用md-virtual-repeat实现双向无限滚动?

7
我已经实现了一个使用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>

基本上,它是一个水平的日期列表(带有其他信息),您可以在其中滚动。您可以滚动到未来的日期。运作良好。
现在,我还想向左滚动,以查看过去的日期。
我正在寻找一种从中间开始的方法(即今天的日期)。我尝试通过控制器设置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>

我该如何配置md-virtual-repeat-containermd-virtual-repeat,以允许向左和向右滚动?
更新:这里有一个Codepen的沙盒,展示了我想通过一个按钮向左滚动的情况。 https://codepen.io/christiaanwesterbeek/pen/pLRQgg 更新2:将md-top-index设置为某个正整数可以实现双向滚动。但是,Angular Material网站上给出的带有md-top-index示例并不是关于无限滚动的。我的问题的解决方案在于md-top-index与无限滚动相遇的地方。
1个回答

0

好的,回答你的问题:

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

简单来说:

我到处寻找这个答案,但是我找不到任何东西,我想你也是一样,所以我从angular cdn下载了angular-material.js本地文件,看看他们如何处理这个问题,以下是代码片段:

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

这就是我发现他们依赖于身体方向来指导无限滚动的方式,所以如果您不想改变您的html文档方向,您将不得不下载它,编辑此部分并使用它来代替cdn,但是...它不能按预期工作;

在正常情况下,从左到右滚动将增加this.scrollLeft变量,并且正如您在片段中看到的那样,它被用于各处,它将增加offsettranslateX(),所有内容都将落入正确的位置,

但是,如果您从右向左滚动,handleScroll_函数将把this.scrollOfsset设置为视图的宽度,并且当您向左滚动时,this.scrollLeft将减少而不是增加,一旦您到达您的前25个的末尾,一切都将分崩离析,

我尝试通过console.log所有变量并将rtlltr进行比较,以查看何时何地出现问题。我尝试围绕值和操作进行实验,但没有成功。你也可以尝试实验,也许我错过了什么(但嘿,问题只是关于改变方向,对吧?:P)

我建议你尝试其他东西(就像上面的评论中提到的那些)

我希望这可以帮助你或者至少给你一个想法,祝你好运。

编辑:

由于这取决于body的方向,因此您只能向左或向右滚动,不能同时进行,即使您设置了md-top-index并从中间开始(使用dir =“ltr”),您只会在一侧(向右)拥有无限滚动,如果您返回,它只会显示已加载的旧数据。

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

顺便说一下:人们想要这个功能是为了反向垂直滚动(用于聊天应用程序),虽然有未解决的问题,但由于他们转向了 Angular 2.x 及以上版本,因此不太可能添加。

底线是:如果您想要在仅使用配置的情况下在两侧滚动,恐怕是不可能的,如果您绝对需要此功能,则需要修改 angular-material.js 来适应您的需求。


看起来你认为我只需要向左滚动,但实际上我需要向两个方向滚动。这种从右到左的方法不允许双向滚动。 - Christiaan Westerbeek
我编辑了我的答案,使其更加精确。我知道你想要在两侧滚动,也许我表达得不太好,但我详细说明了如何向左滚动可能会很困难,因为在开头(左侧)添加块会破坏索引和其他所有内容,因为使用 dir="rtl" 时,新块被添加到末尾,这只是一个方向问题,块并没有真正添加到开头。 - Taki
md-top-index设置为正整数可以实现双向滚动。但是在Angular Material网站上给出的md-top-index示例并不是关于无限滚动的。我的问题的解决方案就在于md-top-index与无限滚动的结合。我希望能够激励您拥有这个解决方案并获得奖励 :) - Christiaan Westerbeek
嗯,我明白你的意思了。设置md-top-index将跳转到该索引(我在这里看到了https://codepen.io/colinskow/pen/jbVaRj),并在编辑中提到了它,但是当它返回并到达起点时,它将停止。我认为这个想法是在两个方向上无限滚动,就像当您向左滚动并到达`0`时,将开始看到`-1,-2,-3`等。我在链接中找到了示例,但我没有考虑将“设置md-top-index”添加到答案中,因为它不是无限滚动,我希望能获得赏金,因为这将是我的第一个,但决定权在你手中 :) - Taki
我很感激你的努力,但是你的回答更像是你调查的记录。我会把赏金给一个真正的解决方案。 - Christiaan Westerbeek
我还有24小时的时间来颁发奖金。如果你能在这段时间内让它工作,我会把奖金授予你。24小时后,我就不能再授予你了......我知道有一种解决方案,而不需要修改angular-material.js。只需要在getItemAtIndex、fetchMoreItems_方法中实现一些智能化处理。可能涉及到两个数组。一个用于向一个方向移动,另一个用于向相反的方向移动。 - Christiaan Westerbeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接