具有流畅,无限滚动的最佳开源网格

iLe*_*ing 9 performance datagrid infinite-scroll angularjs

当我开始处理当前项目时,我被赋予了相当艰巨的任务 - 构建一些本质上可以替代人们在公司内部使用的大型电子表格的东西.

这就是为什么我们认为分页表永远不会工作,老实说我认为分页是愚蠢的.在分页表上显示动态变化的数据是蹩脚的.说第2页上的项目,下一次数据更新可以登陆页面.

所以我们需要构建一个具有漂亮无限滚动的网格.不要误会我的意思,我尝试了很多不同的解决方案.首先,我构建了vanilla ng-repeat的东西并尝试使用ng-infinite-scroll,然后从UI.Utils中进行ng-scroll.这很快让我发现滚动变得非常缓慢,我甚至没有使用任何疯狂的东西,如复杂的细胞模板,ng-ifs或过滤器.很快,表演成了我最大的痛苦.当我开始添加诸如可调整大小的列和自定义单元格模板之类的东西时,没有浏览器可以再处理所有这些绑定.

然后我尝试了ng-grid,起初我很喜欢它 - 易于使用,它有一些我需要的很好的功能,但很快我意识到 - ng-grid非常糟糕.当前版本充满了bug,所有贡献者都停止修复它们并切换到下一个版本.只有上帝知道什么时候可以使用.ng-grid比偶然的van-ng重复得多.

我一直在努力寻找更好的东西.trNgGrid看起来不错,但过于简单化,并没有提供我想要开箱即用的功能.

ng-table与ng-grid没什么不同,可能会导致我同样的性能问题.

当然,我需要找到一种优化绑定的方法.尝试绑定一次 - 不满意,网格仍然是滞后的.(upd:angular 1.3提供{{::foo}}一次性绑定的语法)

然后我尝试了React.最初的实验看起来很有希望,但是为了构建更复杂的东西,我需要学习React细节,除此之外感觉有点非anguleresque并且谁知道如何测试使用angular + react构建的指令.我为构建良好的自动化测试所做的所有努力都失败了 - 我找不到让React和PhanthomJS相互喜欢的方法(这可能是更多Phantom的问题.是否有更好的无头浏览器)另外React没有解决"追加到DOM" "问题 - 当你将新元素推入数据数组时,几毫秒浏览器会阻止UI线程.那当然是完全不同类型的问题.

在看到我的挣扎之后,我的同事(在服务器方面工作)抱怨我已经花了太多钱,试图解决性能问题.他让我尝试了SlickGrid,告诉我故事这是如何最好的网格小部件.老实说,我试过了,很快就想烧掉我的电脑.那件事完全取决于jQuery和一堆jQueryUI插件,我拒绝突然降到中世纪时期的网络开发并失去所有角度的好处.不,谢谢.

然后我来了ux-angularjs-datagrid,我真的非常非常喜欢它.它使用一些智能坏屁股算法来保持响应速度.项目很年轻,但看起来非常有前景.我能够构建一些具有大量行的基本网格(我的意思是大量的行),而不会偏离角度zen和滚动仍然平滑的方式太多.不幸的是,它不是一个完整的网格小部件解决方案 - 你不会有可调整大小的列和开箱即用的其他东西,文档有点缺乏,等等.

我也发现了这篇文章,并对此有了复杂的感觉,这些家伙应用了一些非文明的黑客攻击角度,而且很可能那些会破坏角度的特征版本.

当然,至少有一些付费选项,如Wijmo和Kendo UI.那些与angular兼容,但是显示的示例是非常简单的分页表,我不确定是否值得尝试它们.我可能最终会遇到相同的性能问题.此外,你不能有选择地只为网格小部件支付,你必须购买整个套件 - 我可能永远不会使用的狗屎.

所以,最后我的问题 - 是否有良好的,保证的,不那么痛苦的方式来获得具有无限滚动的漂亮网格?有人能指出好的例子,项目或网页吗?使用ux-angularjs-datagrid或更好地使用angular和react来构建我自己的东西是否安全?有人试过Kendo或Wijmo网格吗?

请!不要投票支持关闭这个问题,我知道stackoverflow上有很多类似的问题,我几乎读过它们中的每一个,但问题仍然存在.

lau*_*ent 5

也许问题不在于现有的小部件,而在于您使用它的方式。您必须了解,超过 2000 个绑定的角度摘要周期可能需要很长时间才能使 UI 平滑呈现。同理,页面上的 html 节点越多,使用的内存就越多,您可能会达到浏览器的容量,以平滑的方式呈现这么多节点。这就是人们使用这种“蹩脚”分页的原因之一。

最后,要获得“平滑”效果,您需要实现的是限制页面上显示的数据量。要使其透明,您可以在滚动时进行分页。

这个 plunker通过smart-table向您展示了这个想法。向下滚动时,加载下一页(向上滚动时必须实现上一页)。并且任何时候的最大行数都是 40。

function getData(tableState) {

            //here you could create a query string from tableState
            //fake ajax call
            $scope.isLoading = true;

            $timeout(function () {

                //if we reset (like after a search or an order)
                if (tableState.pagination.start === 0) {
                    $scope.rowCollection = getAPage();
                } else {
                    //we load more
                    $scope.rowCollection = $scope.rowCollection.concat(getAPage());

                    //remove first nodes if needed
                    if (lastStart < tableState.pagination.start && $scope.rowCollection.length > maxNodes) {
                        //remove the first nodes
                        $scope.rowCollection.splice(0, 20);
                    }
                }

                lastStart = tableState.pagination.start;

                $scope.isLoading = false;
            }, 1000);

        }
Run Code Online (Sandbox Code Playgroud)

每当用户向下滚动并达到阈值时都会调用此函数(出于性能原因当然会使用节流阀)

但重要的部分是,如果您加载了超过给定数量的数据,您将删除模型中的第一个条目。