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

时间:2014-09-04 23:38:08

标签: angularjs performance datagrid infinite-scroll

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:4)

可能问题不在于现有的小部件,而在于您使用它的方式。 您必须了解超过2000个绑定角度摘要周期可能需要很长时间才能使UI平滑渲染。同样的想法是,您在页面上拥有的html节点越多,您将使用的内存就越多,您可能会达到浏览器容量以平滑方式呈现如此多的节点。这是人们使用这个" lame"分页。

最后你需要达到什么才能获得一些东西"顺畅"是限制页面上显示的数据量。为了使其透明,您可以在滚动上进行分页。

This 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);

        }

只要用户向下滚动并达到阈值(当然由于性能原因而节流),就会调用此函数

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

答案 1 :(得分:2)

我想提请你注意Angular Grid。我遇到了和你说的完全相同的问题,所以最终编写(和共享)我自己的网格小部件。它可以处理非常大的数据集,并且具有出色的滚动功能。