Nested models-table usage

ember-models-table v.2 has expandedRowComponent instead of expandedRowTemplate. Let’s check how to show another table there. First of all, you should know that Component (it’s name is in the expandedRowComponent) receives only known list of parameters:

  • record – record-object shown in the current row
  • visibleProcessedColumns – list of table’s visible columns
  • themeInstance – theme instance used in the table
  • messages – messages used in the table
  • Several action handlers

You should set columns as an array with defaults for table columns (see docs/column) to render table correctly. So, we can’t do something like this:

{{! won't work }}
{{models-table columns=columns data=model expandedRowComponent="models-table"}}

We have to do a proxy-component expanded-row like this one:

1
2
3
4
5
// app/components/expanded-row.js
import Component from '@ember/component';
export default Component.extend({
  internalColumns: [/* ... */]
});
1
2
3
4
5
{{! app/templates/components/expanded-row.hbs}}
{{models-table
  data=internalData
  columns=internalColumns
}}

Theme from parent component isn’t applied to the nested table automatically. That is why you may override it or even take another one. You should remember that “internal” theme can’t be called themeInstance. It will be overridden by parent theme instance otherwise. Why should I focus on this? Pretty often developers call properties passed to the Component with names same to Component attribute names. In this case, it can play a cruel joke and take a little time to find a solution to the problem “why correct theme is not applied?”

Let’s see a real example with two Models – klan and warboss (say hello to Warhammer). They are related as one-to-many. One klan may has many warbosses, however each warboss belongs to only one klan.

1
2
3
4
5
6
7
8
9
// app/models/klan.js
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
 
export default Model.extend({
  name: attr('string'),
  warbosses: hasMany('warboss')
});
1
2
3
4
5
6
7
8
9
// app/models/warboss.js
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
 
export default Model.extend({
  name: attr('string'),
  klan: belongsTo('klan')
});

“External” table will output list of klans and “internal” will show warbosses for selected klan.

External table usage:

1
2
3
4
5
6
{{models-table
  data=model
  columns=columns
  themeInstance=themeInstance
  expandedRowComponent=expandedRowComponent
}}

Properties columns and themeInstance are declared in the parent scope:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Ember from 'ember';
import SemanticUiTheme from '../themes/semanticui';
 
export default Ember.Controller.extend({
  themeInstance: SemanticUiTheme.create(),
  expandedRowComponent: 'expanded-row',
  columns: [
    {component: 'expand-row', disableFiltering: true, mayBeHidden: false},
    {propertyName: 'id'},
    {propertyName: 'name'},
    {propertyName: 'colors'},
    {propertyName: 'combat-specialty'}
  ]
});

First column contains Component with buttons for toggling row content. Other four columns are just fields from Records klan. Component expand-row has two buttons and two action handlers:

1
2
3
4
5
6
7
8
9
10
11
12
13
// app/components/expand-row.js
import Ember from 'ember';
 
export default Ember.Component.extend({
  actions: {
    collapseRow(index, record) {
     this.get('collapseRow')(index, record);
    },
    expandRow(index, record) {
      this.get('expandRow')(index, record);
    }
  }
});
1
2
3
4
5
6
7
{{! app/templates/components/expand-row.hbs }}
{{#if isExpanded}}
  <a href="#" {{action "collapseRow" index record bubbles=false}} class={{themeInstance.collapseRow}}>Hide warbosses</a>
  {{else}}
  <a href="#" {{action "expandRow" index record bubbles=false}} class={{themeInstance.expandRow}}>Show warbosses</a>
  {{/if}}
{{yield}}

Value for isExpanded is bound from parent context. You can find full list of parameters passed to the expand-row in the docs – docs/column#component.

Last but not least is a component expanded-row. It’s pretty simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
// app/components/expanded-row.js
import Ember from 'ember';
import SemanticUiTheme from 'app/themes/semanticui';
 
export default Ember.Component.extend({
  internalThemeInstance: SemanticUiTheme
    .extend({table: 'ui sortable selectable inverted table'})
    .create(),
  columns: [
    {propertyName: 'id'},
    {propertyName: 'name'}
  ]
});
1
2
3
4
5
6
7
8
9
10
{{! app/templates/components/expanded-row.hbs}}
{{models-table
  data=record.warbosses
  columns=columns
  themeInstance=internalThemeInstance
  showColumnsDropdown=false
  showGlobalFilter=false
  useFilteringByColumns=false
  showComponentFooter=false
}}

As you can see, both Component use theme SemanticUI, however some theme’s properties are overridden in the internal table. Attribute name for theme-property is internalThemeInstance and not themeInstance.

Demo is available on the ember-twiddle Nested models-table.

, , ,

Add comment

Top ↑ | Main page | Back