2
votes

I have a resource route in my Ember app that successfully loads the model its supposed to per the model hook of the route. While that model is being loaded, I'm able to use a loading route that displays an animated gif to let the user know.

In that same view, I'm rendering a list items in a hasMany relationship for that model. As a possibly important aside, the list in the view is actually rendered using an abstracted view that requires the controller to return the items in the relationship using a specific property name rather than the name of the actual relationship property on the model.

The problem: I'm able to display the relationship items, but they take a second or two to load, during which there's no indication to the user that they are loading. Is there a way to track the status of loading of that relationship?

Below is some of the code involved:

// From router...
App.ItemRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('item', params.item_id);
  }    
});

// From item model...
App.Item = DS.Model.extend({
  name: DS.attr('string'),
  things: DS.hasMany('thing', {
    async: true
  })
});

// From controller...
App.ItemController = Ember.ObjectController.extend({
  myList: function() {
    return this.get('things');
  }.property('things')
});

// From view...
{{#each v in myList}}
  <div>{{v.id}}</div>
{{else}}
  <div>Your list is empty.</div>
{{/each}}
3

3 Answers

1
votes

Have a look at the flags that are made available in Promises: Ember.PromiseProxyMixin

What you are asking can be achieved with isSettled:

{{#if things.isSettled}}
  {{#each things}}
    {{id}}
  {{else}}
    Your list is empty
  {{/each}}
{{else}}
  {{!-- Show loading spinner here --}}
  Loading...
{{/if}}

In order for this to work you need to trigger the request of the things records. You can do this in the afterModel callback of the route:

App.ItemRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('item', params.item_id);
  },

  afterModel: function(model) {
    return model.get('things');
  }    
});
0
votes

Try this, i haven't tested it but i think it should work.

 // From controller...
 App.ItemController = Ember.ObjectController.extend({
   thingsLoaded : false,
   myList: function() {
       if(this.get('thingsLoaded').then){
           var self = this;
           return this.get('things').then(function(data){
              self.set('thingsLoaded', true);
           });
       } else {
           return this.get('things');  
       }
   }.property('things')
 });
-3
votes

I think you should create two functions

function loading(){
//display gif
}

function loadingOff(){
//hide gif
}

And then add these functions inside the functions that takes time to load.

EX:

function loadImage(){
loading();
//code
loadingOff();
}