I’m trying to use Datatables in my EmberJS application.
In a regular jQuery project, I would always use the document ready event and fire off the .datatables();
invocation in there.
$(document).ready(function() {
$('.has-datatable').dataTable();
});
Obviously such an approach doesn’t work in an Ember application.
After some internet searching, I found this solution that appears to work at first glance:
MyEmberApp = Ember.Application.create();
MyEmberApp.CompaniesIndexView = Ember.View.extend({
didInsertElement: function(){
console.log("DONE"); // This logs properly when I switch to this view EVERY TIME! :)
this.$('.has-datatable').dataTable();
}
});
This works, the datatables plugin is run against my table defined in my .hbs
template, but some of the rows/cells are empty, and in the console I see:
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM.
If I disable this fix and run the template, I see the plain old table filled in properly with all the data I need.
How can I accomplish what I’m aiming for? I just need to run $('.has-datatable').dataTable();
guaranteed on a view rendering (or a document-ready-like trigger) and based on the documentation for Ember, didInsertElement
was the place to do it.
I struggled with these exact issues. I found that the initial table load had incomplete rows but then visiting another page and coming back made it work.
I initially used the didInsertElement
hook. When that didn’t work, I hooked directly into the Ember run loop after the render
event. When that didn’t work, out of desperation, I just wrapped the dataTables()
call in a ridiculous setTimeout()
call (i.e. the setTimeout
function that native javascript gives us). Amazingly, setting this to even a delay of 0 seconds fixed the issue!
But then every time I would visit this page after the initial visit, there would be a momentary flicker while the DOM was updating. Ultimately, I concluded there is a fundamental impedance mismatch between the world of datatables, which assumes it is free to manipulate the DOM whenever it pleases, and Ember, which manages all DOM manipulation for us.
For this reason, I wrote my own paginator. See Pagination/Sorting/Filtering for a beginner - #4 by josh_padnick.
For more details on my datatables struggles see dom - Calling jQuery Plugin with EmberJS Creates Race Condition - Stack Overflow.
Haha, literally just found and left you a comment on your SO question. Unfortunately we’re in crunch time and I don’t have the time to roll my own thing.
Do you happen to know of any other lib that works well with Ember out of the box?
Wow, that is pretty crazy. So, the only way I was able to get my datatables to render nicely was when I was dealing with a sufficiently small amount of data that the race condition was hidden. That is obviously not a very stable long-term solution.
It took me about 2 days to write the full paginator mixin setup (not including the controllers I had to write on the API side). So, if that’s not an option, my only other thought is that, if you can get by with client-side paginator only, try using some of the tutorials online. My favorite one was:
http://resistor.io/blog/2013/10/01/simple-pagination-in-ember-arraycontrollers/
Thanks for the info. I’m ultimately going to settle for this monkey patch:
MyEmberApp.CompaniesIndexView = Ember.View.extend({
didInsertElement: function(){
setTimeout(function() {
this.$('.has-datatable').dataTable();
}, 1);
}
});
It works, but feels like a terrible hack. Maybe someone has successfully integrated DataTables into an Ember app somewhere.