0

I want to know when all content has rendered the first time, but Ember.run.scheduleOnce('afterRender' isn't enough because there are promises in the template.

{{#each entity in model.entities}}
  {{entity.anotherEntity.name}}
{{/each}}
{{!-- more like above --}}

Where entities and anotherEntities are async relationships and promises. The afterRender hits before that inner content has rendered. My current solution is:

Ember.run.scheduleOnce('afterRender', this, function() {
  Ember.RSVP.all([
    this.model.get('entities').then(function(entities) {
      return Ember.RSVP.all(entities.map(function(entity) {
        return entity.get('anotherEntity');
      }));
    }),
    // more like above
  ]).then(function() {
    console.log('done-rendering');
  });
});

Is there a better way to do it? This might not even be enough because there could be a split second between when the last promise resolves and the last section of template renders. Maybe I need another afterRender or similar check after all the promises resolve to be sure.

Kelly Selden
  • 1,238
  • 11
  • 21

1 Answers1

0

If you're going to use the afterRender queue, you want to schedule the call after your work is done, but before your work is rendered. Meaning that calling it before your promise resolves is likely going to involve timing issues (as you pointed out). If I were you, I would schedule the call after your promise resolves.

this.model.get('entities').then(function(entities) {
    return Ember.RSVP.all(entities.map(function(entity) {
        return entity.get('anotherEntity');
    });
}).then(function() {
    Ember.run.scheduleOnce('afterRender', this, function() {
        // Your work is finished
        // You can now schedule more work for after rendering
    });
});

Unfortunately I don't know of a much more elegant way than this. In general, the afterRender queue isn't used very often (I only use it when wrapping third party libraries in components) so there's no reason to make it easier to use.

GJK
  • 37,023
  • 8
  • 55
  • 74