ember.jsember-bootstrap

tabs dynamic component waiting before switching to next tab


I'm using the custom tabs config but seem to have a problem loading dynamic content (components within tab panes).

The component loads promise/s or does some processing on init, and when switching to a new tab it will not switch immediately but wait until the component finishes initialization.

ie:

{{#bs-tab customTabs=true as |tab|}}

    {{#bs-nav type="tabs" as |nav|}}
        {{#nav.item active=(eq tab.activeId "edit")}}<a href="#edit" role="tab" {{action tab.select "edit"}}>Edit</a>{{/nav.item}}

     {{/bs-nav}}

    {{#tab.pane elementId="edit" title="Edit"}}
       {{#if (eq tab.activeId "edit")}}
          <h2>TEST</h2>//->this does not show until some-component finishes initialization

          {{some-component}}//->does some processing, promises or whatever on init
      {{/if}}
    {{/tab.pane}}

{{/bs-tab}}

I tried manually setting and keeping track of the activeId by hooking into the onChange event but have the same effect.


Solution

  • I am not sure whether I got what you are asking correctly; but here are my opinions about your case. First of all, the component's init method runs as soon as it is rendered in the template whether or not the related tab is currently active or not. This is good in terms of application performance; because even the init methods of components for which the tabs are not visible will start running. However; you have avoided that with the following condition!

       {{#if (eq tab.activeId "edit")}}
    

    If you use such if statements then every time you make a tab switch; a new component will be rendered and the component at the previous tab will be destroyed!!! That might kick you hard if you have some heavy work at your components; creating and destroying components would be costly. Think twice before doing so and make sure this is what you want!

    If you have some stuff to display after initialization of component finishes within a tab you can make use of ember actions as usual. Please take a look at the following twiddle that I have prepared for you.

    In this example, application.hbs contains two tabs in which two different components reside (my-component and my-component2). my-component init method waits for 3 seconds before being done with initialization where as my-component2 waits for 10 seconds. I have passed the same action (componentAtTabDoneInitializing) at application.js controller to both components so as the controller will be notified when each component finishes its initialization. The application controller keeps track of which component is done initializing by this way; hence you can make use if tab1FinishedInitializing, tab2FinishedInitializing flags within application.hbs.