如何使用md-virtual-repeat允许双向无限滚动?



我已经使用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以允许向左和向右滚动?

更新:这是一个沙盒,其中包含情况的代码笔,我想通过一个向左滚动的按钮来容纳它。 https://codepen.io/christiaanwesterbeek/pen/pLRQgg

更新 2:将md-top-index设置为某个正整数允许双向滚动。但是在有md-top-index的角度材料站点给出的例子并不是关于无限滚动的。我的问题的解决方案是md-top-index在哪里遇到无限滚动。

很好..回答你的问题:

您可以通过将html文档的body标签更改为<body dir="rtl">

快速概述:

我到处寻找这个,但我找不到任何东西,我想你也找到了,所以我从本地的 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以满足你的需求。

最新更新