sajid sharlemin
sajid sharlemin

Reputation: 162

How to know when a handlebars template has finished rendering/rerendering

I have a handlebars template to display a table.

The content changes on a drop down select which makes an ajax call to get data for the template. Now I need to add a CSS class to a table row dynamically after the data gets fetched. Now I have to add a timeout of 100 ms so the selector works.

Because at the point I am setting the class the first time the table tr does not exist. How do I know if the handlebars template is done rendering the new data ( first time ) so I do not have to rely on timeOut function. This is the controller function that sets data for the template and add CSS.

    updateData: function(data,index)
    {
        this.set('data',data);

        setTimeout(function() {
            console.log('sleep');
            Ember.$('.table tr').removeClass("active");
            Ember.$('.table tr:eq(' + (index+1) + ')').addClass("active");
        }, 100);

    }

Upvotes: 0

Views: 900

Answers (2)

Josh
Josh

Reputation: 36

You can use the Ember.run.scheduleOnce method to schedule the CSS class manipulation to occur after the afterRender queue is emptied (i.e. the dom is fully rendered)

Click here for more information about the Ember Run Loop

So in your example,

updateData: function(data,index) {
    this.set('data',data);

    Ember.run.scheduleOnce('afterRender', this, function() {
        console.log('sleep');
        Ember.$('.table tr').removeClass("active");
        Ember.$('.table tr:eq(' + (index+1) + ')').addClass("active");
    });

}

Upvotes: 0

givanse
givanse

Reputation: 14953

This is the type of problem that is best solved using an Ember.View, it will make things easier.

You can create a view for each row in your table and in each view you can use the classNameBindings property that will add or remove any number of CSS classes according to the property they are bound to.

See: http://emberjs.com/api/classes/Ember.View.html

In your template you would have something like:

<table>
  {{#each item in model}}
    {{view 'my-row' ...}}
  {{/each}}
</table>

And in your view you would have something like:

Ember.View.extend({
    tagName: 'tr',
    classNameBindings: ['active']
})

Upvotes: 1

Related Questions