Виртуальная прокрутка SlikGrid — огромный набор данных

Мне удалось расширить пример загрузки Ajax, чтобы он соответствовал моему требование.

В текущей реализации загрузчик в slick.remotemodel.js имеет переменную с именем data, которая представляет собой массив объектов javascript. Этот массив является источником данных для сетки. По мере того, как мы продолжаем прокручивать, хотя в DOM отображается только размер страницы строк, массив javascript продолжает расти.

Каков верхний предел размера объекта javascript? Есть ли вероятность нехватки памяти? Допустим, мой набор данных имеет порядок ~ 125000 строк с несколькими столбцами ~ 10. Я понимаю, что для определения размера набора данных может потребоваться дополнительная информация, но с приведенной выше информацией может ли кто-нибудь предоставить некоторые данные?

Чтобы справиться с описанными выше сценариями, я обновил код. Пожалуйста, смотрите мое редактирование. Пожалуйста, дайте мне знать, если я что-то упустил.

Изменить: Мое решение состояло в том, чтобы вызвать метод очистки в методе onsuccess, чтобы убедиться, что массив данных имеет только PAGESIZE # элементов.

(function ($) {
    /***
    * Ajax loading example which is an extension
    * of the http://mleibman.github.com/SlickGrid/examples/example6-ajax-loading.html
    * example.
    */
    function RemoteModel() {
        // private

        var fromPage = 0; 
        var rows = 0; 

        var PAGESIZE = 250; 
        var data = { length: 0 };
        var h_request = null;
        var req = null; // ajax request

        // events
        var onDataLoading = new Slick.Event();
        var onDataLoaded = new Slick.Event();


        function init() {
        }


        function isDataLoaded(from, to) {
            for (var i = from; i <= to; i++) {
                if (data[i] == undefined || data[i] == null)
                    return false;
            }

            return true;
        }


        function clear() {
            for (var key in data) {
                delete data[key];
            }
            data.length = 0;
        }


        function ensureData(from, to) {

            if (req) {
                req.abort();

                for (var i = req.fromPage; i <= req.toPage; i++)
                    data[i * PAGESIZE] = undefined;
            }

            if (from < 0)
                from = 0;

            fromPage = Math.floor(from / PAGESIZE);
            var toPage = Math.floor(to / PAGESIZE);

            while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage)
                fromPage++;

            while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage)
                toPage--;

            rows = (((toPage - fromPage) * PAGESIZE) + PAGESIZE);

            if (fromPage > toPage || ((fromPage == toPage) && data[fromPage * PAGESIZE] !== undefined)) {

                // TODO:  look-ahead
                return;
            }

            var url = "" ; // IMPORTANT : you should set this to your url which returns the data

            if (h_request != null) {
                clearTimeout(h_request);
            }

            h_request = setTimeout(function () {

                for (var i = fromPage; i <= toPage; i++)
                    data[i * PAGESIZE] = null; // null indicates a 'requested but not available yet'

                onDataLoading.notify({ from: from, to: to });

                req = $.ajax({
                    url: url,
                    dataType: 'json',
                    success: function (response) {
                        onSuccess(response);
                    },
                    error: function () {
                        onError(fromPage, toPage);
                    }
                });


                req.fromPage = fromPage;
                req.toPage = toPage;

            }, 100);
        }


        function onError(fromPage, toPage) {
            alert("error loading pages " + fromPage + " to " + toPage);
        }

        function onSuccess(response) {

            //Solution to keep the data array bounded to pagesize: Call the clear method to have only PAGESIZE elements in the data array at any given point
            clear(); 

        //The visisble # of rows in the viewport could be only ~20 but
           // i'm populating PageSIZE which acts like the client-side cache, in my case 250,
      // so that I avoid too many server hops
            var from = fromPage * PAGESIZE, to = from + PAGESIZE;

            data.length = response.count;

            for (var i = 0; i < response.Fields.length; i++) {
                data[from + i] = response.Fields[i];
                data[from + i].index = from + i;
            }

            req = null;

            onDataLoaded.notify({ from: from, to: to });
        }


        function reloadData(from, to) {
            for (var i = from; i <= to; i++)
                delete data[i];

            ensureData(from, to);
        }


        init();

        return {
            // properties
            "data": data,

            // methods
            "clear": clear,
            "isDataLoaded": isDataLoaded,
            "ensureData": ensureData,
            "reloadData": reloadData,

            // events
            "onDataLoading": onDataLoading,
            "onDataLoaded": onDataLoaded
        };
    }

    // Slick.Data.RemoteModel
    $.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel}} });
})(jQuery);
enter code here

Спасибо


person StudentForever    schedule 22.08.2011    source источник


Ответы (1)


Мое решение состояло в том, чтобы вызвать метод clear в методе onsuccess, чтобы убедиться, что массив данных имеет только PAGESIZE # элементов. Это сохранит только данные в массиве объектов javascript, который требуется, а все остальное должно быть установлено как неопределенное.

person StudentForever    schedule 23.08.2011
comment
Была ли ваша сетка редактируемой? Может ли пользователь выбрать ряд элементов, которые могут исчезнуть с экрана, а затем удалить их? - person Daryn; 07.10.2017