cell().data( set ) vs. row().data( d )
cell().data( set ) vs. row().data( d )
Using DataTables 1.10.5, Data source is a JavaScript array of objects, var myData.
I'm trying to get my head around the DataTables data model.
A. This construct, updates the table display but it does not update the array, myData
.
var obj = {item1 : "This", item2 : "does not", item3 : "update the", item4 : "array."};
table.row(1).data(obj);
B. While this construct updates both the table display and myData
.
var cell = table.cell(4,1);
cell.data('Big Coffee Maker 4');
C. And, of course, this construct updates both the data in the array and refreshes the display:
myData[2].item1 = 'This';
myData[2].item2 = 'updates';
myData[2].item3 = 'the';
myData[2].item4 = 'array';
table.rows().invalidate().draw();
1. What's the difference between cell().data( set )
and row().data( d )
? Is the above behavior expected?
2. row(n).data( d )
always seems to write to the DataTable row n in display order, regardless of the modifier. What's the best practice or how do I map back to the array?
3. Further, and related to #2, myData
gets programmatically sorted (while DataTable, as mentioned is unordered). After myData
is sorted this call table.rows().invalidate().draw();
does not cause DataTable to display the data in the new sorted order. My interpretation of invalidate()
is, it should.
4. With C, before myData
is sorted the 3rd row of the table is updated (zero based array). But after the sort, the 8th row of the table is updated. So rows().invalidate().draw()
does not change the display per the sort but I have to write to the array in such a way as to consider the impact of the sort().
5. I guess a bottom line question would be, given all the ways there is to manipulate data, 1is there one approach that is better than another? And given that the source data's order has to change, what's the best way to keep DataTables (both display and Data()
) in sync with it. That is, what should I be using for an index to myData
from DataTables?
Thank you.
This question has accepted answers - jump to:
Answers
Hi,
Excellent set of questions - thanks! So, the key thing to understand here is that DataTables retains the object references, but not the array. So when you update
myData
DataTables doesn't know anything about that since it has effectively thrown that array away and used its own for data storage.But when you update the objects in it, those objects are still referenced by
myData
(and else where in DataTables since you can have multiple references to a single object in Javascript) hence you see the changes.In short, updates to
myData
have no effect, but updates to the objects it contains does!Conversely, to explain why
row().data()
as a setter doesn't effectmyData
or the object in it, the data object passed in replaces DataTables referenced object. So it no longer has a reference to the object for that row inmyData
. As I noted, DataTables has its own array of data (actually it is an array of objects and the data for each row is a property of each object, so it isn't as simple asmyData
) so it stores the reference to the new object.Now, if you want to update the original object what you could do is:
However, you must keep in mind that deleting entries and adding new ones to
myData
will have no effect. The DataTables API must be used for that.In general I would suggest that you forget about
myData
once you have passed it into DataTables. I do want to make updates so that DataTables will be able to retain it, but I suspect that is going to be rather complex!Could you explain a little about what you are trying to achieve and perhaps I can help suggest how it might be done in DataTables.
Regards,
Allan
Allan, thanks a lot. That clears up some things for me. This is the key I had not understood:
As you suggest, I'll try to explain a bit about what I'm doing, but first, a few more, hopefully quick questions.
1. Given that
myData
array is thrown away and that I can populate DataTables withrow.add()
(orrows.add()
), do I needmyData
? I assume not. I ask because I don't want to initializeDataTable({"data": null})
and get bitten later on because a data source is required under the hood.2. The app gets 100% of the data for DataTables from either user input or programmatically (JavaScript) generated data based on rules. Many rules depend upon the physical display location of a row (and the row is frequently not selected).
If I use DataTable ordering option how do I read from and write to say the physical display location row 3, column 1?
For me, these 4 statements return the same value:
and these write to the same display location which isn't the physical row 3 due to the applied ordering:
2b. And I guess an implied question, since all the above produce the same results, what is the
modifier
parameter for or how is it used?3. The various way to call
data()
seem to return values. That is the result is static. What is return is not a reference to the data. Am I understanding correctly?Thanks.
Two small notes about the DataTables documentation:
A. Here:
The option isn't actually a JavaScript object is it? Rather the option should be 2
number
parameters.B. Here:
Original is an alias of itself?
I would say not. If you are using
rows.add()
just have an empty table - no need to populate it if it doesn't need to be at initialisation!The reason the statements you have aren't working is that the selectors (the first two parameters) are indexes. The third parameter effects only the return data structure - not what is actually selected. You need to modify the selectors:
Of course if you are using a
click
event on the cell you want to get data for you could just usetable.cell(this).data()
since the cell selector can be a node.Its a bit like the situation with
data
andmyData
discussed above. The array is not a reference to anything, it is just a container, but the objects contained in it are. So the array is static, yes. The objects inside are not.Yes, you can use
{ row: y, column: x }
as acell-selector
. The key thing here is thatcell()
can take a dt-type cell-selector, or both a
dt-type row-selectorand
dt-type column-selector` which is what you describe - two indexes.Doh - its an alias of
index
. Fix committed - thanks!Allan