Question
I 've just gotten my directive to pull in a template to append to its element like this:
# CoffeeScript
.directive 'dashboardTable', ->
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
(scope, element, attrs) ->
element.parent('table#line_items').dataTable()
console.log 'Just to make sure this is run'
# HTML
<table id="line_items">
<tbody dashboard-table>
</tbody>
</table>
I am also using a jQuery Plugin called DataTables. The general usage of it is like this: $('table#some_id').dataTable(). You can pass in the JSON data into the dataTable() call to supply the table data OR you can have the data already on the page and it will do the rest.. I am doing the latter, having the rows already on the HTML page.
But the problem is that I have to call the dataTable() on the table#line_items AFTER DOM ready. My directive above calls the dataTable() method BEFORE the template is appended to the directive's element. Is there a way that I can call functions AFTER the append?
Thank you for your help!
UPDATE 1 after Andy's answer:
I want to make sure that the link method does only get called AFTER everything is on the page so I altered the directive for a little test:
# CoffeeScript
#angular.module(...)
.directive 'dashboardTable', ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
element.find('#sayboo').html('boo')
controller: lineItemIndexCtrl
template: "<div id='sayboo'></div>"
}
And I do indeed see "boo" in the div#sayboo.
Then I try my jquery datatable call
.directive 'dashboardTable', ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
element.parent('table').dataTable() # NEW LINE
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
}
No luck there
Then I try adding a time out :
.directive 'dashboardTable', ($timeout) ->
{
link: (scope,element,attrs) ->
console.log 'Just to make sure this gets run'
$timeout -> # NEW LINE
element.parent('table').dataTable()
,5000
controller: lineItemIndexCtrl
templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
}
And that works. So I wonder what goes wrong in the non-timer version of the code?
Answer
If the second parameter, "delay" is not provided, the default behaviour is to execute the function after the DOM has completed rendering. So instead of setTimeout, use $timeout:
$timeout(function () {
//DOM has finished rendering
});