使用大型数据集进行分页,复选框选择,排序和过滤的slickgrid?

时间:2014-05-22 18:31:34

标签: jquery asp.net-mvc-4 slickgrid

我设置了一个slickgrid,并尝试将500,000条记录传递给它或更少(500k是绝对最大值)。

我进行了分页,排序,内联列过滤以及所有设置的复选框行选择,并使用了一些注意事项。

浏览器崩溃或询问(你确定要继续运行这个长时间运行的脚本吗?)每当我在IE8和任何FireFox实例中加载超过100k记录的任何数据时。 (IE8在我所在的公司范围内使用,因此我暂时没有选择告诉他们升级)

我正在使用MVC,数据来自多个ajax请求,因为json数据只能这么长。

我想要的效果是,当用户从“ddlFiles”中选择一个文件时,根据选择的结果填充网格。

前端代码如下:

<script type="text/javascript">
    var grid;
    var finalData = [];
    var columnFilters = {};
    function getDate(jsonDate) {
        // added checks for undefs.. djweaver 
        if (typeof jsonDate === 'undefined') {
            return "01/01/0000";
        }
        var dt1 = new Date(parseInt(jsonDate.substring(6, jsonDate.length - 2)));
        var month = (dt1.getMonth() + 1);
        var day = dt1.getDate();
        var year = dt1.getFullYear();

        if (month < 10) { month = "0" + month; }
        if (day < 10) { day = "0" + day; }

        var dt1String = month + "/" + day + "/" + year;
        return dt1String;
    }
    $("#myGrid").height(($("#ddlPage").val() * 25) + 59);
    $("#ddlClients").change(function () {
        $("#loadingDialog").dialog('open');
        $("#progressbar").fadeIn('fast');
        if (finalData.length > 0) {
            grid.destroy();
        }
        while (finalData.length > 0) {
            finalData.pop();
        }
        setTimeout(function () {
            $("#ddlFiles").val(0);
            $("#myGrid").empty();
            $("#loadingDialog").dialog('close');
            $("#progressbar").fadeOut('fast');
        }, 5000);
    });
    $("#ddlFiles").change(function () {
        if ($("ddlFiles").val() != 0) {
            if (finalData.length > 0) {
                grid.destroy();
            }
            while (finalData.length > 0) {
                finalData.pop();
            }
            $("#myGrid").empty();
            $(".selEdit").show();
            $("#loadingDialog").dialog('open');
            $("#progressbar").fadeIn('slow');
            $.ajax({
                type: "GET",
                url: "Intake/getDataInfo",
                dataType: "text",
                data: { numRecords: $("#ddlFiles").val() },
                cache: false,
                success: function (info) {
                    var counter = (info / 5000) + 1;
                    for (var x = 0; x <= counter + 1; x++) {
                        $.ajax({
                            type: "GET",
                            url: "Intake/getData",
                            dataType: "json",
                            data: { counter: x },
                            cache: false,
                            success: function (json) {
                                $.merge(finalData, json);
                            }
                        });
                    }
                    waitOnData(info);

                }
            });
        }
    });
    var timeoutId = null;
    function waitOnData(totalCount) {
        var percent = (finalData.length / totalCount)*100;
        $("#progressbar").width(percent + "%");
        if (percent < 100) {
            timeoutId = setTimeout(function () {
                waitOnData(totalCount);
            }, 300);
        } else {
            popGrid(finalData);
        }
    }

    function popGrid(data) {

        var dateFormatter = function (row, cell, value, columnDef, dataContext) {
            return getDate(value);
        };
        var dataView; 
        var columns = [];
        var checkboxSelector = new Slick.CheckboxSelectColumn({});
        columns.push(checkboxSelector.getColumnDefinition());
        columns.push(
            { id: "LastName", name: "Last Name", field: "LastName", sortable: true, width: 75 },
            { id: "FirstName", name: "First Name", field: "FirstName", sortable: true, width: 75 },
            { id: "Hicn", name: "Hicn", field: "Hicn", sortable: true, width: 75 },
            { id: "DOB", name: "DOB", field: "DOB", sortable: true, formatter: dateFormatter, width: 75 },
            { id: "PlanEffDate", name: "Plan Eff Date", field: "PlanEffDate", formatter: dateFormatter, sortable: true, width: 80 },
            { id: "PrimaryCarrier", name: "Primary Carrier", field: "PrimaryCarrier", sortable: true, width: 100 },
            { id: "SecondaryCarrier", name: "Secondary Carrier", field: "SecondaryCarrier", sortable: true, width: 100 },
            { id: "SecondaryId", name: "SecondaryId", field: "SecondaryId", sortable: true, width: 80 }
        );

        var options = {
            editable: true,
            multiColumnSort: false,
            enableCellNavigation: true,
            showHeaderRow: true,
            headerRowHeight: 30,
            asyncEditorLoading: true,
            forceFitColumns: true,
            explicitInitialization: true
        };

        function filter(item) {
            for (var columnId in columnFilters) {
                if (columnId !== undefined && columnFilters[columnId] !== "") {
                    var c = grid.getColumns()[grid.getColumnIndex(columnId)];
                    var itemString = item[c.field].toString();
                    if (itemString.indexOf('/Date') >= 0) { itemString = getDate(itemString) }
                    if (itemString.toLowerCase().lastIndexOf(columnFilters[columnId].toString().toLowerCase(),0) === -1) {
                        return false;
                    }
                }
            }
            return true;
        }        
        dataView = new Slick.Data.DataView({ inlineFilters: true });
        grid = new Slick.Grid("#myGrid", dataView, columns, options);
        var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options);
        grid.setSelectionModel(new Slick.RowSelectionModel({ selectActiveRow: false }));
        grid.registerPlugin(checkboxSelector);
        var pager = new Slick.Controls.Pager(dataView, grid, $("#pager"));
        dataView.onRowCountChanged.subscribe(function (e, args) {
            grid.updateRowCount();
            grid.render();
        });
        dataView.onRowsChanged.subscribe(function (e, args) {
            grid.invalidateRows(args.rows);
            grid.render();
        });
        grid.onHeaderRowCellRendered.subscribe(function (e, args) {
            $(args.node).empty();
            if (args.column.id != "_checkbox_selector") {
                $("<input type='text'>")
                                            .data("columnId", args.column.id)
                                            .val(columnFilters[args.column.id])
                                            .appendTo(args.node);
            }
        });
        $(grid.getHeaderRow()).delegate(":input", "change keyup", function (e) {
            var columnId = $(this).data("columnId");
            if (columnId != null) {
                columnFilters[columnId] = $.trim($(this).val());
                dataView.refresh();
            }
        });
        grid.onHeaderRowCellRendered.subscribe(function (e, args) {
            $(args.node).empty();
            if (args.column.id != "_checkbox_selector") {
                $("<input type='text'>")
                                .data("columnId", args.column.id)
                                .val(columnFilters[args.column.id])
                                .appendTo(args.node);
            }
        });
        grid.onSort.subscribe(function (e, args) {
            var isDate = (finalData[0][args.sortCol.field].indexOf("/Date") >= 0) ? true : false;
            dataView.fastSort(args.sortCol.field, isDate, args.sortAsc);
            //grid.invalidate(); 
            $("#progressbar").fadeOut('fast');
            $("#loadingDialog").dialog('close');
        });
        dataView.syncGridSelection(grid, true);
        grid.init();
        dataView.beginUpdate();
        dataView.setItems(data, "Id");
        dataView.setFilter(filter);
        dataView.setPagingOptions({ pageSize: $("#ddlPage").val() });
        dataView.endUpdate();
        $("#progressbar").fadeOut('fast');
        $("#loadingDialog").dialog('close');
    }
    $("#chkPage").click(function () {
        grid.setSelectedRows("0,1,2,3,4");
        alert($.session.get("selected"));
    });
    function SetPager() {
        $('#txtPagingChange').keyup(function () {
            var number = $("#txtPagingChange").val();
            dataView.setPagingOptions({ pageNum: number - 1 });
            $('#txtPagingChange').focus();
            $('#txtPagingChange').val('');
            $('#txtPagingChange').val(number);
        });
    }
    $(function () {
        $(".selEdit").hide();
        $("#btnConfigs").click(function () {
            $("#ConfigDialog").dialog('open');
        });
        $("#ConfigDialog").dialog({
            autoOpen: false,
            modal: true,
            width: 350,
            height: 135,
            closeOnEscape: false,
            beforeclose: function (event, ui) { return false; },
            dialogClass: "noclose",
            show: {
                effect: "slide",
                duration: 1000
            },
            hide: {
                effect: "fold",
                duration: 1000
            }
        });

        $("#btnOverrideConfirm").dialog({
            autoOpen: false,
            modal: true,
            width: 400,
            height: 135,
            closeOnEscape: false,
            beforeclose: function (event, ui) { return false; },
            dialogClass: "noclose",
            show: {
                effect: "slide",
                duration: 1000
            },
            hide: {
                effect: "fold",
                duration: 1000
            }
        });

        $("#btnSubmitGrid").click(function () {
            $("#btnOverrideConfirm").dialog('open');
        });
        $("#btnSubmitConfig").click(function () {
            $("#myGrid").height(($("#ddlPage").val() * 25) + 59);
            dataView.setPagingOptions({ pageSize: $("#ddlPage").val() });
            $("#ConfigDialog").dialog('close');
        });
        $("#progressbar").progressbar({ value: false });
        $("#loadingDialog").dialog({
            autoOpen: false,
            modal: true,
            width: 730,
            height: 100,
            closeOnEscape: false,
            beforeclose: function (event, ui) { return false; },
            dialogClass: "noclose",
            show: {
                effect: "puff",
                duration: 10
            },
            hide: {
                effect: "slide",
                duration: 10
            }
        });
    })

</script>

1 个答案:

答案 0 :(得分:0)

我同意la ghiscoding的建议,你必须对数据实现延迟加载。

以下是关于如何实现分页的想法(不使用Slick.Controls.Pager):

  • 实现要在后端部分获取的数据的分页/限制,只需从ajax请求传递页码
  • 在前端部分
  • ,首先获取分页信息(总行数,总页数)
  • 为上一页和下一页添加2个按钮,当单击上一个/下一个按钮时,获取数据并传递页码(当前页面减去/加1),当没有更多前一个/时,禁用上一个/下一个/下一页要获取
  • 将当前页面保存在javascript
  • 中的全局var / object中
  • 每次获取后刷新网格(网格仅包含并显示当前页面的行)

这样做意味着您不必渲染/获取所有数据并立即将其存储到网格中。但是,您可以对网格中的数据执行的其他功能也可以部分完成(例如,排序只会对网格中的当前项目进行排序,而不是对所有最终数据进行排序)