1
votes

In one route I render multiple outlets, and foreach outlet I load its content using the its controller with the content variable. I would like to show a loading view for each outlet, but don't know how to since there are no loading route for them (and so I can't just create an handlebar).

I have no issue displaying the loading view when my app starts, using a loading handlebar. But for my outlets I have no routes neither resources to it, so there is no loading route or loading template available when checking the Ember console.

I need to find a trick so I can, in my outlet, display a loading view while the content is being fetched.

Any idea?

The route where I'm inserting the outlet:

App.ProfileRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render(); // default behavior, renders the default template

        // loads documents outlet
        this.render('documents', {
            into: 'profile',
            outlet: 'documents',
            controller: 'documents'
        });

        // load other outlets after
    }
});

The associated handlebar:

<script type="text/x-handlebars" data-template-name="profile">
  <div id="profile-sections">
    {{outlet documents}}
    {{outlet accounts}}
    {{outlet contacts}}
  </div>
</script>

Controller:

App.DocumentsController = Ember.ArrayController.extend({
    itemController: 'document',

    content: function () {
        return this.store.findAll('document');
    }.property()
});

Then, in the documents.hbs template I just loop over the documents, link them to the item controller, and have my logic. That's all. I've tried to add the loading function into the actions of the controller, but it didn't work (just logged some text but nothing showed up).

Thanks,

2

2 Answers

2
votes

personally I'd add all those finds to the model hook, and use the default loading route. Something like this (I guessed on the models for accounts and contacts).

App.ProfileRoute = Ember.Route.extend({
  model: function(){
    return Ember.RSVP.hash({
      documents: this.store.find('document'),
      accounts: this.store.find('account'),
      contacts: this.store.find('contact')
    });
  }
});

Then in your template use render

<script type="text/x-handlebars" data-template-name="profile">
  <div id="profile-sections">
    {{render 'documents' documents}}
    {{render 'accounts' accounts}}
    {{render 'contacts' contacts}}
  </div>
</script>
0
votes

So I just want to add that I did a little bit different, so I can still keep my outlets, and not rendering view just like that. I have some needs that makes things kind of complicated, here my solution:

Route:

App.ProfileRoute = Ember.Route.extend({
    model: function(){
        return Ember.RSVP.hash({
            accounts: this.store.findAll('account'),
            documents: this.store.findAll('document'),
            contacts: this.store.findAll('contact')
        });
    },

    setupController: function(controller, model) {
        this.controllerFor('accounts').set('model', model.accounts);
        this.controllerFor('documents').set('model', model.documents);
        this.controllerFor('contacts').set('model', model.contacts);
    },

    renderTemplate: function() {
        this.render(); // default behavior, renders the default template

        // loads accounts outlet
        this.render('accounts', {
            into: 'profile',
            outlet: 'accounts',
            controller: 'accounts'
        });

        // loads documents outlet
        this.render('documents', {
            into: 'profile',
            outlet: 'documents',
            controller: 'documents'
        });

        // loads contacts outlet
        this.render('contacts', {
            into: 'profile',
            outlet: 'contacts',
            controller: 'contacts'
        });
    }
});

Then in the template:

<script type="text/x-handlebars" data-template-name="profile">
  <div id="profile-sections">
    {{outlet documents}}
    {{outlet accounts}}
    {{outlet contacts}}
  </div>
</script>

And the easy loading handlebar:

<script type="text/x-handlebars" data-template-name="profile/loading">
  <div id="profile-loading">
    My loading spinner and text
  </div>
</script>

And it works perfect.