How to render so it is not blocked waiting for model to be resolved?


#1
import Ember from 'ember';
import LoadingSliderMixin from '../mixins/loading-slider';

export default Ember.Route.extend(LoadingSliderMixin, {
  ajax: Ember.inject.service(),
  // geolocation: Ember.inject.service(),
  model() {
    return this.get('ajax').request('/filters')
  
  },
  // setupController(cont,model){
  //   this._super(cont,model)
  //   
  // }
});


I want to load the ajax response after rendering is done. how can i do it?


Parallel data render template
#2

There are a few ways to do this.

1) kick off the request in the route but don’t wait for it.

  model() {
    return {
      filters: this.get('ajax').request('/filters')
    };
  }

2) Feed the request down to a component to kick off only once rendered

You still send the data down from the route, but instead of loading it there you just build a contract for it there.

model() {
  return {
      loadData: () => { return this.get('ajax').request('/filters'); }
    };
}

Then in the template you have a component that lazy loads the data.

render-later.js

import Ember from 'ember';

const {
  Component,
  run
  } = Ember;

export default Component.extend({
  tagName: '',

  wait: 0,
  shouldRender: false,
  _renderTimer: null,
  load: null,
  model: null,

  didInsertElement() {
    this._renderTimer = run.later(() => {
      this.get('load')().then((data) => {
        if (!this.get('isDestroyed')) {
          this.set('shouldRender', true);
          this.set('model', data);
        }
      });
    }, this.get('wait'));
  },

  willDestroy() {
    this._super();
    run.cancel(this._renderTimer);
  }
});

render-later.hbs

{{#if shouldRender}}
  {{yield model}}
{{/if}}

usage

{{#render-later load=model.loadData as |data|}}
  {{!-- ... use {data} here... --}}
{{/render-later}}

With this we can easily choose to further delay loading the data by adjusting wait to something longer than 0ms.

{{#render-later load=model.loadData wait=5000 as |data|}}
  {{!-- ... use {data} here... --}}
{{/render-later}}

You could further combine this with https://github.com/DockYard/ember-in-viewport to only load some data once a component is on or near the screen.


#3

I will try that out , thanks.