У меня есть два компонента. Первый представляет таблицу элементов, а второй представляет один элемент. Первый повторяет второй много раз.
Компонент списка (app-list
):
<table>
<tr *ngFor="let item of items" [item]="item" app-item></tr>
</table>
Компонент изделия (app-item
):
<td>
<img src="https://someimage.com/{{item.img}}.jpg">
</td>
<td>
<h3>{{item.name}}</h3>
</td>
<td>
{{item.description}}
</td>
Чтобы это работало, мне пришлось использовать селектор атрибута для компонента app-item
:
@Component({
selector: '[app-item]'
})
Это прекрасно работает.
Теперь я хочу улучшить его и добавить второй ряд в каждый app-item
. Моя проблема в том, что тег tr
лежит в компоненте app-list
вместо компонента app-item
. Я думал, что если я переместу его в компонент app-item
, я мог бы добавить еще tr
и иметь возможность показывать две строки на один элемент. Так вот что я сделал. После этого я использовал ng-container
, чтобы повторить элементы в моем app-list
, чтобы избежать добавления тега-обертки вокруг моих двух строк:
<ng-container *ngFor="let item of items" [item]="item" app-item></ng-container>
Это решение не сработало. Я получил следующую ошибку:
ERROR TypeError: el.setAttribute is not a function
at EmulatedEncapsulationDomRenderer2.push../node_modules/@angular/platform-browser/fesm5/platform-browser.js.DefaultDomRenderer2.setAttribute (platform-browser.js:1089)
at EmulatedEncapsulationDomRenderer2.push../node_modules/@angular/platform-browser/fesm5/platform-browser.js.EmulatedEncapsulationDomRenderer2.applyToHost (platform-browser.js:1157)
at DomRendererFactory2.push../node_modules/@angular/platform-browser/fesm5/platform-browser.js.DomRendererFactory2.createRenderer (platform-browser.js:1015)
Можете ли вы помочь мне решить эту ошибку или предложить другую реализацию?
РЕДАКТИРОВАТЬ: РЕШЕНИЕ
Лучшая версия @Serhiy предлагает
Таблица:
<table>
<app-item *ngFor="let item of items" [item]="item" remove-component-tag></app-item>
</table>
Директива:
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[remove-component-tag]'
})
export class RemoveComponentTagDirective {
constructor(private el: ElementRef) {
let element = el.nativeElement;
let children = el.nativeElement.childNodes;
setTimeout(()=>{
let reversedChildren = [];
children.forEach(child => {
reversedChildren.unshift(child);
});
reversedChildren.forEach(child => {
element.parentNode.insertBefore(child, element.nextSibling);
});
element.remove(element);
}, 0);
}
}
Тайм-аут необходим по некоторым причинам и работает даже с 0.