1

I have an application using ember with two tabs, one for articles, and other for hotArticles. Here's the template:

<a class="item" data-tab="hot">Hot</a>
<a class="item active" data-tab="all">All</a>
<div class="ui tab" data-tab="all">
  {{article-list articles=articles}}
</div>
<div class="ui tab" data-tab="hot">
  {{article-list articles=hotArticles}}
</div>

articles is supposed to return api/articles, and hotArticles is supposed to return api/articles?filter=hot, here's the route and controller:

export default Ember.Route.extend({
    model: function() {
        return this.store.find('article');
    }
});

export default Ember.ArrayController.extend({
  articles: function() {
    return this.get('model');
  }.property('model'),

  hotArticles: function() {
    return this.store.find('article', { filter: 'hot' });
  }.property('')
});

This is fundamentally wrong. Obvious problem is when the page is loaded, both requests are made but hotArticles should not be loaded until the tab is selected.

One possible solution might be to separate the routes for each tab, but that will break the template. The tab functionality works without introducing any routes and I want it to keep it that way. Specifically I am using semantic-ui tabs.

user3995789
  • 3,452
  • 1
  • 19
  • 35

2 Answers2

1

I have this exact problem and the way that I handle it is by surrounding the tab content in condition blocks. For instance:

<div class="ui tab" data-tab="all">
    {{#if showAllTab}}
        {{article-list articles=articles}}
    {{/if}}
</div>
<div class="ui tab" data-tab="hot">
    {{#if showHotTab}}
        {{article-list articles=hotArticles}}
    {{/if}}
</div>

This does require you to maintain an extra set of variables to toggle the tabs on and off, but it does exactly what you want. It removes those parts from the DOM completely when not in use, and only processes the data behind the component when it's actually put into the DOM.

I'm sure there are other ways, but this way is simple and works well.

GJK
  • 37,023
  • 8
  • 55
  • 74
1

@GJK, Thanks for the answer, I solved the problem by dropping semantic-ui built-in tab functionality and using ember query params instead.

{{#link-to 'index' (query-params tab="hot") class="right item"}}Hot{{/link-to}}
{{#link-to 'index' (query-params tab="all") class="right item"}}All{{/link-to}}

<div class="ui bottom attached active tab segment">
  {{article-list articles=articles}}
</div>

I have only one div.tab.segment without data-tab attributes, and tab items are links with query params.

export default Ember.ArrayController.extend({
  queryParams: ['tab'],
  tab: hot,
  articles: function() {
    return this.get('model');
  }.property('model')
});


export default Ember.Route.extend({
  queryParams: {
    tab: {
      refreshModel: true
    }
  },
  model: function(params) {
    return this.store.find('article', { tab: params.tab });
  }
});

This looks neat, and query params have the extra feature to link to specific tab. Let me now what you think.

user3995789
  • 3,452
  • 1
  • 19
  • 35
  • Turns out this approach is fit when the layout/model of each tab is the same. eg: each tab showing a list of articles filtered by a condition. I don't see how routes can help with different layouts for each tab. – user3995789 Dec 11 '14 at 06:36