What are the right hooks in Ember.js to implement a "loading" state in a route?

StackOverflow https://stackoverflow.com/questions/23585659

  •  19-07-2023
  •  | 
  •  

Question

While a Position model loads, I want to show a loading/spinner message in the template. I am not being able to achieve that.

{{#if loading}}
  <div class="spinner"></div>
{{else}}
  <div>Here goes the position</div>
{{/if}}

Given the router

App.Router.map(function() {
  this.resource('article', { path: '/:id' }, function() {
    this.route('position', { path: '*position_id' });
  });
});

my approach in the ArticlePositionRoute is the following:

App.ArticlePositionRoute = Em.Route.extend({

  actions: {
    loading: function() {
      var controller = this.get('controller');
      if (controller) controller.set('loading', true);
      return false;
    }
  },

  setupController: function(controller, model) {
    controller.set('loading', false); // BEFORE _super
    this._super(controller, model);
    controller.set('loading', false); // AFTER _super
  },

  model: function(params) {
    return promiseThatTakesAWhile(); // slow fetch model
  },

  afterModel: function(model) {
    var self = this;
    return promiseThatTakesAWhile().then(function(result) {
      model.set('result', result);
      self.set('controller.loading', false); // THIS THROWS "Uncaught Error: Property set failed: object in path "controller" could not be found or was destroyed."
    });
  }

});

In afterModel, the controller is not available, throws Uncaught Error: Property set failed: object in path "controller" could not be found or was destroyed.

In setupController, when the set goes before the _super call, it blows with Error: Assertion Failed: Cannot delegate set('loading', false) to the 'content' property of object proxy <App.ArticlePositionController:ember726>: its 'content' is undefined., if I put it after the _super call, the view already calls didInsertElement and errs because it can't find the right div in the template (basically, it's too late).

What are the proper hooks to set/unset the 'loading' flag? I think I have the set loading true in the right place, but I don't know where to put set loading false.

When the Ember docs say actions: { loading: function(transition, originRoute) { // displayLoadingSpinner(); ..., if that example in the docs was fully developed, what would it look like?

Était-ce utile?

La solution

You should use the built in loading route. You may think it needs to exist as a child route of the resource that is taking time to load, but that's incorrect, it needs to be a child route of the parent's resource (which will have already resolved). Or in your case the loading route needs to exist as ArticleLoadingRoute. It will be shown any time any resource/route immediately under it is taking time to load.

Here's an example where I've forced two resources to take a while to load

http://emberjs.jsbin.com/OxIDiVU/465/edit

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top