Использование вложенных таблиц ember-models-table

Во второй версии аддона ember-models-table вместо expandedRowTemplate пришел expandedRowComponent. Разберем ситуацию, когда в нем надо вывести другую таблицу. В первую очередь надо знать, что Компонент, чье имя находится в expandedRowComponent, получает заранее известный набор параметров, а именно:

  • record — запись, отображаемая в текущей строчке
  • visibleProcessedColumns — массив с видимыми колонками
  • themeInstance — экземпляр темы, применяемой в таблице
  • messages — сообщения, выводимые в таблице
  • Несколько обработчиков событий

Чтоб таблица models-table отобразилась корректно, ей надо передать columns, с начальными настройками для колонок (см. docs/column). Из этого следует, что сделать нечто подобное не получится:

{{! не сработает }}
{{models-table columns=columns data=model expandedRowComponent="models-table"}}

Придется сделать один компонент-прослойку expanded-row в виде:

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
}}

Так как тема из родительской таблицы автоматически не применяется к дочерней, то вы можете переопределить ее или же вообще выбрать другую. Тут главное помнить, что «внутреннюю» тему нельзя создавать в свойстве с именем themeInstance, иначе она будет перезаписана «родительской». Казалось бы, зачем заострять на этом внимание? Часто свойства, передаваемые в какой-то Компонент, в называют одноименно с атрибутами самого Компонента. В данном случае это может сыграть злую шутку и отнять немного времени на поиск решения проблемы «почему у меня не та тема применилась?»

Рассмотрим реальный пример с двумя Моделями — klan и warboss (Вархаммер, привет). Между ними связь один-ко-многим. У одного клана может быть много варбоссов, но варбосс принадлежит только к одному клану:

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')
});

Таблица «верхнего» уровня пусть выводит список кланов, а «внутренняя» будет выводить варбоссов для выбранного клана.

Отрисовка внешней таблицы:

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

К родительском контексте свойства columns и themeInstance объявлены как:

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'}
  ]
});

В первой колонке выводится Компонент с кнопками сворачивания/разворачивания содержимого строчки. Остальные четыре колонки — это просто данные из Записей klan. Компонент expand-row — это две кнопки и два обработчика событий для кликов по ним:

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}}

Значение isExpanded Компонент expand-row получит из родительского для себя контекста. Полный список параметров, которые передаются в Компонент ячейки таблицы можно найти по ссылке docs/column#component.

Осталось показать, что из себя представляет внутренний Компонент expanded-row:

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
}}

Как видим, для обоих Компонентов мы используем тему SemanticUI, однако для внутренней таблицы переопределяем ее некоторые свойства. И, опять-таки, для внутренней таблицы имя свойства с темой взято не themeInstance, а internalThemeInstance.

Рабочая демка доступна на ember-twiddle по ссылке Nested models-table.

, , ,

Оставить комментарий

Top ↑ | Main page | Back