开发者

SlikGrid Virtual Scrolling - Huge dataset

开发者 https://www.devze.com 2023-03-30 01:15 出处:网络
I was able to extend the Ajax-Loading Example to suit my requirement. In the current implementation, the loader in slick.remotemodel.js has a variable called data which is an array of javascript obj

I was able to extend the Ajax-Loading Example to suit my requirement.

In the current implementation, the loader in slick.remotemodel.js has a variable called data which is an array of javascript objects. This array is the datasource for the grid.As we keep scrolling, although the DOM has only page size of rows rendered, the javascript array keeps growing.

What is the upper limit of size of javascript object ? Is there a possibility of running out of memory ? Lets say my data set is in the开发者_JS百科 order of ~125000 rows with multiple columns ~10. I realize more information might be required to define the size of the dataset but with the above info, can somebody provide some inputs ?

To handle the above scenarios, I updated the code. Please see my edit. Please let me know if I'm missing anything.

Edit: My solution was to call the clear method in onsuccess method to make sure the data array has only PAGESIZE # of items.

(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

Thanks


My solution was to call the clear method in onsuccess method to make sure the data array has only PAGESIZE # of items. This will only keep data in the javascript object array which is required and everything else should be set to undefined.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号