| Page 1 of 1 | [ 5 posts ] |
|
When I iterate through a DataTable having 250+ rows and attempt to either update a cell or modify a row,
it will either hang (usually displaying 'A script on this page may be busy, or may have stopped responding' message) or take 15+ seconds to complete. code below: Code: <button id="pushme">BOOM</button> <div id="tableGoesHere"></div> <script> YUI().use('node', 'datatable', 'datatable-mutable', function(Y) { var columns = [ {key: "action"}, {key: "existsInSource"}, {key: "existsInTarget"}, {key: "fileName"}, {key: "fileID"}, {key: "sourcePath"}, {key: "selectedOption"} ]; var data = []; for (var i=0; i < 250; i++) { data.push({ fileID: 'fileID' + i, fileName: 'fileName' + i, sourcePath: 'sourcePath' + i, existsInSource: true, existsInTarget: true, selectedOption: 1, action: 'action' + i }); } var dataTable = new Y.DataTable({ columns: columns, data: data, scrollable: 'y' }).render("#tableGoesHere"), rowCount = dataTable.data.size(); Y.one('#pushme').on('click', function() { var selectedIndex = Math.floor((Math.random()*10)+1); Y.log(selectedIndex); dataTable.data.each(function (record, i) { // either action below causes the problem record.set('selectedOption', selectedIndex); dataTable.modifyRow(i, {'selectedOption': selectedIndex}); }); // Also tried: // for (var i=0; i < rowCount; i++) { // record = dataTable.data.item(i); // record.set('selectedOption', selectedIndex); // //dataTable.modifyRow(i, {'selectedOption': selectedIndex}); // } }); }); </script> Last edited by swpage on Thu May 03, 2012 2:40 pm, edited 1 time in total. |
|
Each modification is triggering a re-render. In 3.5.0, mutation triggered re-rendering isn't optimized. Here's a gist that is an initial implementation of what will be in core for 3.6.0: https://gist.github.com/2295032
in the mean time, you can use that, or do: Code: dataTable.data.each(function (record) { record.set('selectedOption', selectedIndex, { silent: true }); }); dataTable.syncUI(); or Code: dataTable.data.invoke('set', 'selectedOption', selectedIndex, { silent: true }); dataTable.syncUI(); This will silence the mutation events, then re-render the table once after all the changes have been made to the data. HTH |
|
Thanks for your quick response. Using the 'silent' attribute along with syncUI works great.
One side-effect for my application is it re-sets an HTML select menu I have within one of the column headers. Doing a set('selectedIndex', selectedIndex) after syncUI does nothing, presumably as the headers are immutable. I can't seem to find anything on how to dynamically set data within the column headers. Thanks |
|
Hmm, the select complicates any potential solution because it's typical to subscribe to the 'change' event of select elements, but 'change' doesn't bubble, which means you can't use a delegate subscription (until I create the synthetic event patch).
So it's likely that you're storing a reference to the Node for the select element in the header and subscribing to its 'change' event. What's happening is that syncUI() rerenders the table, including the headers, which means the select element that's there after syncUI() is not the same select element that you initially captured. You have a couple options: Probably best option for you is to replace the new select with the one you initially captured after the syncUI(). Code: dataTable.render(...); var headerSelect = dataTable.one('contentBox').one('.foo'); Y.Do.after(function () { this.get('container').one('.foo').replace(headerSelect); }, dataTable.head, 'render'); Another, less comprehensive, solution is to call dataTable.body.render() instead of dataTable.syncUI(); In the future, after I create the bubbling 'change' synthetic event, it would be best to do: Code: dataTable.delegate('change', function (e) { // code that updates the records }, '.yui3-datatable-columns .foo', dataTable); |
|
I had success by capturing the header select node prior to the updates and syncUI(), then doing the replace afterwards:
Code: selectChangeEvent = function(menu) { headerSelect = Y.one('#selectAll'); dataTable.data.some(function (record, recordIndex) { record.set(..); ... }); dataTable.syncUI(); Y.one('#selectAll').replace(headerSelect); } Thanks again! |
| Page 1 of 1 | [ 5 posts ] |
| You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum |
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info
Powered by phpBB® Forum Software © phpBB Group