xMartin
xMartin

Reputation: 245

In an Ember view, what's the best way to run code after the rerendering of an internal child view?

I found a lot of questions about how to initialize jQuery plugins with dynamic data etc and usually the answer is that you should use the didInsertElement hook. My problem is that when using ember-data, initially the view is inserted empty and the template vars are filled afterwards through the bindings. Thus in didInsertElement the elements I need are not there.

I found a solution that works for me but I think there must be a better solution.

In addition to the didInsertElement method I also observe the attributes in the controller and call my code from there, too, wrapped in a Ember.run.next so the child view is rendered before.

Is there a better solution to react to updated child views?

Upvotes: 2

Views: 1745

Answers (2)

S'pht'Kr
S'pht'Kr

Reputation: 2839

I had this problem and came up with a solution: make a handlebars helper that tells you when the sub-section has rendered. Hope that helps some other folks!

Upvotes: 1

Joachim H. Skeie
Joachim H. Skeie

Reputation: 1903

It depends a bit on the size of your application, and the number of elements your view is rendering.

Edit: You might successfully observer the isLoaded property of the RecordArray. Some details here: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/record_arrays/adapter_populated_record_array.js#L21

One option that I have used for views that have a single object as their content is something like:

MyApp.CustomView = Ember.View.extend({
    content: null,

    contentObserver: function() {
        this.rerender();
    }.observes('content')
}

If your view contents is a list, it makes little sense to re render the view for each item in the list, though.

However, I think this approach is fairly similar to what you are already doing, though.

Another approach is to implement your own adapter with Ember Data. This way, you can tell the rest of your application that it's finished loading your data. Something like:

MyApp.Adapter = DS.Adapter.create({
    //Finding all object of a certain type. Fetching from the server
    findAll: function(store, type, ids) {
        var url = type.url;
        jQuery.getJSON(url, function(data) {
            store.loadMany(type, data);
        });

        //Perform some custom logic here... 
    }
}

This should work, but its not as generic as it should/could be though.

Also, you might want to take a look at this commit, which allows for registering a one-time event.

https://github.com/emberjs/ember.js/commit/1809e65012b93c0a530bfcb95eec22d972069745#L0R19

Upvotes: 1

Related Questions