javascriptember.jshandlebars.jsember-routerember-components

remove template in renderTemplate ember route after loading is finished


i made a loading view when the route has to much waiting for the data, this is my route

import Ember from 'ember';
import ENV from '../../config/environment';

export default Ember.Route.extend({
  desaService: Ember.inject.service(),
  model(){
    return Ember.RSVP.hash({
      currentlyLoading:true,
      desas: this.get('desaService').find(ENV.defaultOffset, ENV.defaultLimit),
      desaCount: this.get('desaService').count()
    });
  },
  setupController(controller, model) {
    this.controllerFor('backend.master-desa').set('desas', model.desas);
    this.controllerFor('backend.master-desa').set('currentlyLoading', model.currentlyLoading);
    this.controllerFor('backend.master-desa').set('desaCount', model.desaCount);
  },
  renderTemplate(controller, model){
    let controller2 = this.controllerFor('backend.master-desa');
    if(controller2.get('currentlyLoading')){
      this.render('components/common/loading-view', {
        into:'application'
      });
    }
  },
  actions:{
    loading(transition, originRoute){
      let controller = this.controllerFor('backend.master-desa');
      controller.set('currentlyLoading', true);
      transition.promise.finally(function() {
        controller.set('currentlyLoading', false);
      });
    }
  }
});

first i set currentlyLoading true, then the renderTemplate will be called and showing 'components/common/loading-view' into application.hbs. this is work but i need to remove that 'components/common/loading-view' after the loading actions has complete. please help me :(


Solution

  • You can make use of disconnectOutlet method of router. What you need to do is to call the following to remove the template that is rendered within renderTemplate hook method.

      actions:{
        loading(transition, originRoute){
          let _this = this;
          let controller = this.controllerFor('backend.master-desa');
          controller.set('currentlyLoading', true);
          transition.promise.finally(function() {
            controller.set('currentlyLoading', false);
            _this.disconnectOutlet({
              outlet: '',
              parentView: 'application'
            });
          });
        }
      }
    

    However, if you run your application probably you are going to see that nothing is rendered. Here is the reason:

    renderTemplate hook is run after model is already solved; hence you will see nothing until the model is fully resolved. renderTemplate hook will be run to make a rendering; however loading event within actions will be fired and you will remove the template that is about to be rendered since loading is finished. Hence, you will not achieve what you want with this design approach.

    You need to is to render something before model is fully resolved; and that is explained in the guide specifically. I suggest you to go over it and ask more if you run into some issues.

    I have prepared the following twiddle for you that illustrates both usage of a loading template to show until model is fully resolved and usage of disconnectOutlet to remove a template that is rendered to a specific outlet. I hope this will help you understand better. Best Regards.