fnGetData(): Can I get the actual object instance behind the row?
fnGetData(): Can I get the actual object instance behind the row?
BLSully
Posts: 24Questions: 1Answers: 0
With fnGetData(row), I get back an Object with all my original properties + whatever other custom columns I've defined.
With more and more of my code moving to arrays of complex objects rather than 2d arrays of data, I want to be use the methods available on my 'typed' JS Objects.
[code]
function GameUser() {
this.name = 'someridiculoushandle';
this.score = 15;
}
GameUser.prototype.incrementScore = function( ) { this.score += 1; return this; }
//paraphrased....
//bind array of GameUser to DataTable
aGameUsers = [new GameUser()];
dt.fnAddData(aGameUsers);
//click on row
data = dt.fnGetData(row)[0];
if(data instanceof GameUser) { //this is false
//i want to be able to do this:
data.incrementScore();
}
[/code]
So, can I get to my original objects somehow (either using fnGetData or otherwise)? I have factory methods that convert 'plain' objects into instances, but it seems like a waste when those instances already exist somewhere. I've also tried caching my objects in another array and then looking them up when I get the row data from fnGetData....but that makes me feel incompetent ;)
With more and more of my code moving to arrays of complex objects rather than 2d arrays of data, I want to be use the methods available on my 'typed' JS Objects.
[code]
function GameUser() {
this.name = 'someridiculoushandle';
this.score = 15;
}
GameUser.prototype.incrementScore = function( ) { this.score += 1; return this; }
//paraphrased....
//bind array of GameUser to DataTable
aGameUsers = [new GameUser()];
dt.fnAddData(aGameUsers);
//click on row
data = dt.fnGetData(row)[0];
if(data instanceof GameUser) { //this is false
//i want to be able to do this:
data.incrementScore();
}
[/code]
So, can I get to my original objects somehow (either using fnGetData or otherwise)? I have factory methods that convert 'plain' objects into instances, but it seems like a waste when those instances already exist somewhere. I've also tried caching my objects in another array and then looking them up when I get the row data from fnGetData....but that makes me feel incompetent ;)
This discussion has been closed.
Replies
That's wrong :-(.
fnRender should never has existed and it causing a bit of hassle now, but unfortunately it is also very widely used, so it can't simply be removed at the drop of a hat.
If you look in _fnAddData you will see the slice / $.extend and you can remove that - your method should then work. It means modifying the ore until I've got a more permanent solution - which I hope to have as part of 1.10.
Allan
Thanks for the clear explanation. And I understand about fnRender... if it disappeared at the drop of a hat we would probably just lock the doors to the office and go home ;) Too much of our code from the past 2 years depending on it ;)
I will look at the source of _fnAddData and maybe fork on github.
Thanks again.
-Brendan
I've been maintaining multiple lists and it's no fun. If my own data could instead be shared with datatables, instead of copied, that would be fantastic. It would make life so much easier and probably improve performance (or at least memory consumption). Right now I've got a lot of work-arounds going on to keep things in sync, and things are more complicated than I would like..
I'd also love to be able to update a row that hasn't yet been rendered (bDeferRender). Right now if a row isn't rendered and I try an fnUpdate on it, it doesn't seem to take the new value. But that's another issue entirely I guess..
I've been thinking about what you said and I think a reasonable workaround to this issue might be to keep the slice/extend in there, but keep a reference to the original data source available as well....in my head, something like fnGetOriginalData(row)
I'm not sure what other impacts this might have.... I'm thinking the internals of keeping both DT's 'source' and the original data in sync during fnUpdate/fnDeleteRow operations might get tricky... maybe this isn't such a good idea after all.
Dunno, I'll look sometime when I can think straight... or if you can think of something more appropriate?
Been thinking about this all day, and I'm very tempted to drop fnRender in the next major update (v1.10), with a solid migration path using mRender and mData being provided. v1.10 development should really kick off in November (time set aside for DataTables development :-) ), so I've got until then to kick the idea around, and I realise that it will cause some upgrade pains - but it is a major version change, so if its going to happen before DataTables 2, then this might be the ideal time.
All thoughts are welcome!
@rewen: Absolutely - it is also part of the reason that integrating DataTables with Backbone or Knockout is a real pain at the moment, since the reference is lost.
Regarding the issue on fnUpdate and bDeferRender - that should actually work. Could you open a new thread on that, and link to a test case showing the problem please?
Thanks,
Allan
An initialization parameter makes much more sense. I will investigate that this weekend.
I've been using mRender exclusively in my latest work and I find it much more friendly than fnRender, even disregarding what's going on internally. Not had a chance to use the [, ].prop syntax, but that looks exciting too ;)
Thanks for your input.
Disregard my comment about fnUpdate and bDeferRender. I could've sworn that aoData was reverting to the pre-update state after fnDraw but now it's not doing that.. I'm not sure why it didn't work for me at the time, but it's working fine now. I've even tried on older versions and it's working there, too.
@rewen - Thanks for the update. Good to hear it is working after all :-)
Allan
https://github.com/BLSully/DataTables/
Commit of interest: https://github.com/BLSully/DataTables/commit/3461d5acadd2386566cc4f6267ea6b32d13bca61
@allan: if you know of some other place this boolean might need to be checked, I'd definitely be interested in continuing to maintain this fork until your real solution ends up in 1.10 or 2.0
Still thinking about fnRender... If fnRender is dropped in 1.10 in favour of mRender / mData, then there will be no slice / $.extend required, so the behaviour introduced by your flag would be the default, and only, behaviour. I'm going to experiment a bit more before committing to go down that path, but I think it is the correct one to take.
Regards,
Allan
I made the changes to the source files as you suggested above, but now if If I run ./make.sh in the scripts folder, it fails on jshint (unable to find config). If i run "./make.sh debug", I get the jquery.dataTables.js output file, but it's just the closure, with no JS inside (and a ton of "No such file or directory" errors).
I don't have any experience with this kind of build process and I can't find any posts or tutorials on how to get my environment setup correctly to use your build scripts.
Thanks. -B
[code]
sh -x make.sh debug
[/code]
you will get a complete dump of what bash is trying to do and it will hopefully show some errors (although errors should show in the console anyway). I'm surprised make.sh debug doesn't work - that reasonably simple file concatenation. Perhaps you can dump the output from sh -x into paste bin and link to it?
Allan
Thanks for the help. I'm going to guess the "Cannot remove core/core.data.js\r.build" errors are the issue, but where does the r.build come from? (or ignore me if i'm chasing down the wrong trail) ;)
> echo $SHELL
should tell you. I've only tested my script in bash and there are a few bash specific things in there...
Allan
Thanks, I'll get back to you.
brendan@durin:/media/sf_GitHub/DataTables/media/js$ echo $SHELL
/bin/bash
Just curious.. with this modification everything DataTables does will refer to my original data, correct? I mean not only fnGetData but also fnUpdate, mData, mRender, fnCreateRow, etc?
I assume that with the change each row's _aData properties will simply become references, which is exactly what I want, and therefore all of DataTables functions will be referring to my original data at all times.
Actually, before posting that I decided that I should just check the source code before myself to make sure.. and I found out that when you do a slice() it actually isn't creating an independant copy of the array items, at least not if they are Objects.
Ex:
fnAddData([
['string', Object, Object, Object]
['string', Object, Object, Object]
['string', Object, Object, Object]
]);
That results in the Objects being referenced but the strings being copied. I can actually use that to my advantage (saves me from having to use BLSully's fork) but I don't imagine it's acting as you expected.
To make sure that's in fact how it works I was able to modify the data in one of the _aData Objects for a row and the change was reflected my original data as well. If I change one of the _aData strings then it's only affecting DataTables and my original data remains with the original string.
Yes you are absolutely correct. The array is a copy, but since the "pointers" are pointing to the same objects as before, the reference is retained. A quick of Javascript, but it can be useful.
If you want to live on the bleeding edge, I've committed the change for DataTables 1.10 that makes the change to not copy the data (you can grab it from Github).
Allan
I am working on another project where the previous coder used BLSully's solution but I've run into a snag.
If I change the data for one of the rows and I want to have that one row redrawn.. I have to do an fnUpdate on it, passing in the object that the row is already based upon.
It turns out that if the object being passed in, is not a 'plain' object (in my case it's an instance of something else), fnUpdate breaks.
As a workaround I can probably just tell it to fnUpdate the first column with the value that it already is. But is there a better way? Without redrawing the entire table, ideally.
Ref : http://www.datatables.net/plug-ins/api
FYI Link : http://www.datatables.net/forums/discussion/12403/are-it039s-possable-to-redraw-not-all-data-table-but-only-one-row-or-cell#Item_3
This is another similar discussion thread
The new API in 1.10 is going to have a standing redraw option built in as well as a regular draw :-).
Allan
Allan
Neither a full or a standing redraw actually seem to update the table with the new values from their objects. They still remember the old value. It seems to be cached unless I use fnUpdate. I can see my new value in aoData but I can't get it to re-render the cell to match.
Any tips?
I am new to this can any body help on the same..
@rewen:
> Neither a full or a standing redraw actually seem to update the table with the new values from their objects. They still remember the old value
They would do if you are just changing the data source object and unless you are using the very very latest v1.10 development code. Even then, I think you need to call fnUpdate in order to make sure that all parts of DataTables are using the latest values (i.e. we need to invalidate the cached filtering, sorting etc).
Allan