Nested models and loading screen


#1

Hi People,

I have an application with a hasmany relationship. When the user goes to create a status they can choose from a list of icons (cool, new hot, interesting) that relate to that status.

The problem is I get the loading screen while the create page loads (which is awesome). but then after a few seconds the data comes in for the icons which suddenly pop-up. Is there a way to have the create page loading wait till the icon data is downloaded too? or to have a small sub loader for the icons?

model:

export default DS.Model.extend({
   body: DS.attr('string', { defaultValue: '' }),
   icons: DS.hasMany('icon', { async: true }),
   created_at: DS.attr('date', { readOnly: true }), 
   updated_at: DS.attr('date', { readOnly: true }),
});

controller:

export default Em.Route.extend({
   setupController: function(controller) {
     controller.set('iconList', this.store.find('icon'));
     controller.set('content', this.store.createRecord('status'));
    }
});

thanks heaps!


#2

I’ve been working with a similar issue on my project. We use the loading route in combination with an isLoading property on the controller, which is computed from the loading states of child promises.

Here’s the chunk of code directly from my project:

export default Ember.ObjectController.extend({
  products: function() {
    return this.get('details').getEach('product');
  }.property('details.@each.product'),

  productsPending: function() {
    return this.get('products').getEach('isPending');
  }.property('products.@each.isPending'),

  isLoading: function() {
    var details = this.get('details.isPending'),
        product = this.get('productsPending').uniq().get('firstObject');

    return details || product;
  }.property('details.isPending', 'productsPending.[]')
});

Basically, I have a details model, which belongs to a product. The properties are setup this way, because you can’t chain more than a single property if you’re using @each. So far, this works for me.

I’m using the isLoading property in my template to hide a table of details for a loading spinner with some nice text notifying the user to chill-out for a moment.

IF you wanted to just use the loading route, what you would need to do is utilize the afterModel property in the route to resolve a promise when your child data becomes available.


#3

Wow cool, thank you very much! I will have a tinker and try to get it working on my side.