5

I have a DataTable which is populated from a remote JSON DataSource:

var dataSource = new Y.DataSource.Get({ source: url });

dataSource.plug(Y.Plugin.DataSourceJSONSchema, {
    schema: {
        resultListLocator: "results",
        resultFields:  [ "field1", "field2" ]
    }
});

var table = new Y.DataTable({ columns = ["col1", "col2"] }

table.plug(Y.Plugin.DataTableDataSource, { datasource: dataSource });

table.render("#table");

table.datasource.load({ request: query });

I'm trying to have the data in the table refreshed periodically. A forum poster recommended calling load periodically, which I've tried and it works as I was hoping for (data refreshes without displaying a Loading... message).

Y.later(1000/*ms*/, table.datasource, table.datasource.load, { request: query }, true);

However, I've noticed a memory leak in Chrome. The table cells don't seem to be removed from memory. Chrome's heap profiler is reporting lots of HTMLTableCellElement objects in Detached DOM tree.

Is this the best method of refreshing the data? If so, is there some way to clear out the old table cells?

Alternatives

There is also the datatable-polling module that can do periodic fetching of data. I can't any examples of how this is supposed to be used with a YUI3 DataTable though. However, examples from YUI2 show you can do something the following, which appears to work:

dataSource.setInterval(1000,         
    {
        request: query,
        callback: 
            {
                success: function(e) { table.onDataReturnInitializeTable },
                failure: function() { Y.log("Polling failure", "error"); }
            }
    });

However, it looks like this is just what load is doing under the hood anyway:

load: function(config) {
    config = config || {};
    config.request = config.request || this.get("initialRequest");
    config.callback = config.callback || {
        success: Y.bind(this.onDataReturnInitializeTable, this),
        failure: Y.bind(this.onDataReturnInitializeTable, this),
        argument: this.get("host").get("state") //TODO
    };

    var ds = (config.datasource || this.get("datasource"));
    if(ds) {
        ds.sendRequest(config);
    }
},
juandopazo
  • 6,283
  • 2
  • 26
  • 29
SimonC
  • 6,590
  • 1
  • 23
  • 40

1 Answers1

0

datasource-polling won't help you in this case because Plugin.DataTableDataSource doesn't make the DataTable listen to all changes in the DataSource. The most simple way of polling using Plugin.DataTableDataSource would be to set up the interval yourself like this:

var datasource = new Y.DataSource.IO(...);
var table = new Y.DataTable(...);

table.plug(Y.Plugin.DataTableDataSource, {
  datasource: datasource
});

// call load() every second
var timer = Y.later(1000, table.datasource, 'load', {
  request: foo
}, true);

// later on, stop polling
timer.cancel();

The memory leak you mention is a possibility. DataTable is under ongoing development and it will get better at managing memory. However if you have a reproducible case and thorough measurements you should definitely open an issue at YUI's GitHub repository.

juandopazo
  • 6,283
  • 2
  • 26
  • 29
  • So, just to confirm, `load` should be responsible for cleaning up the memory used by the rows that are getting replaced? – SimonC May 09 '13 at 01:54
  • Actually, `datatable.render` is responsible for that, and when you call `datatable.datasource.load`, `render` is called under the hood. So, yes. – juandopazo May 13 '13 at 13:34