#angular
#angular
Вопрос:
Согласно документации IBM Carbon Design System, можно определить ng-template
и ссылаться на него с помощью @ViewChild
и protected
переменной.
Затем, при определении new TableItem
, следует ссылаться на эту переменную и присоединять данные, связанные с шаблоном, через атрибут let-data
, в итоге:
import {
TableItem,
TableHeaderItem
} from 'carbon-components-angular';
/* ... */
export class HomeComponent implements OnInit {
@ViewChild('customItemTemplate')
protected customItemTemplate: TemplateRef<any>;
/* ... */
initialiseTable(records: any) {
this.model = new TableModel();
this.model.header = [
new TableHeaderItem({ data: 'Column name' }),
/* ... */
];
tableRow = [
new TableItem({ data: { name: 'Full details', link: '/record/' }, template: this.customItemTemplate }),
/* ... */
];
this.model.data = [tableRow];
}
И в HTML моего компонента у меня есть следующее ng-template
:
<ng-template #customItemTemplate let-data="data">
<a [routerLink]="data.link">{{data.name}}</a>
</ng-template>
Я пробовал переключаться между разными версиями: 9.0.0 и 10.0.0.rc.0.
Когда я посмотрел на представление, где должен быть пользовательский шаблон, я вижу [object Object]
.
Кто-нибудь может помочь мне исправить это, чтобы мой шаблон вставлялся правильно, и я мог предоставить ссылку на другое представление?
Обновление: я зарегистрировал это как проблему на GitHub и получил действительно быстрый ответ. Меня попросили предложить сокращенную демонстрационную версию, которую вы можете найти через Codesandbox здесь. Связанная проблема с GitHub здесь
Ответ №1:
Я нашел проблему!
Хотите верьте, хотите нет, но это связано с кодом, предоставленным документацией IBM по разбиению на страницы.
Рассматриваемый код, который по умолчанию вызывает проблемы с пользовательскими шаблонами, используется для функциональности разбивки на страницы в демонстрации:
protected prepareData(data: Array<Array<any>>) {
// create new data from the service data
let newData = [];
data.forEach(dataRow => {
let row = [];
dataRow.forEach(dataElement => {
row.push(new TableItem({
data: dataElement,
template: typeof dataElement === "string" ? undefined : this.paginationTableItemTemplate
// your template can handle all the data types so you don't have to conditionally set it
// you can also set different templates for different columns based on index
}));
});
newData.push(row);
});
return newData;
}
Для справки, вот соответствующая документация. Если вы прокрутите вниз до заголовка «Использовать разбивку на страницы в качестве нижнего колонтитула таблицы», вы увидите код, о котором я говорю 🙂
Решение
Функция должна проверять тип, проходящий при prepareData
вызове во время разбивки на страницы:
protected prepareData(data: Array<Array<any>>) {
// create new data from the service data
const newData: Array<Array<TableItem>> = [];
data.forEach(dataRow => {
const row: Array<TableItem> = [];
dataRow.forEach(dataElement => {
let template;
if (dataElement.template) {
template = dataElement.template;
} else if (typeof dataElement === 'string') {
template = undefined;
} else {
template = this.paginationTableItemTemplate;
}
row.push(
new TableItem({
data: dataElement.data,
template: template
})
);
});
newData.push(row);
});
return newData;
}
И теперь это работает как по маслу.
Я обновил команду через GH и посмотрю о PR для документов по этому поводу — не будет редкостью, что люди копируют код и забывают об этом, как это сделал я. Пользовательские шаблоны начали работать только тогда, когда я вернул всю функциональность, затем я перешел к базовым принципам.