我正在尝试在Angular中的表中插入一行,以显示有关所单击行中对象的信息。数据从服务中获取。我尝试了不同的方法,this one是让我最接近的方法。不幸的是,renderer2.setRootElement()方法删除了单击行的内容。其次,似乎不建议在Angular中使用这样的工作。
模板:
<tbody #tbody>
<tr class="row" *ngFor="let ticket of tickets; let i=index" (click)="createInfoBox($event, i, ticket)" id="row_{{i}}">
<td class="col-md-1" id="ticket_state"> {{ ticket["AsstDoc.ProcState"] }}</td>
<td class="col-md-2" id="ticket_date">{{ ticket["AsstDoc.DocDate"] }}</td>
<td class="col-md-4" id="ticket_office">{{ ticket["AsstDoc.CustName"] }} {{ ticket["AsstDoc.DeliveryAddrNo"] || ticket["Addr.Line1"] }}</td>
<td class="col-md-4" id="ticket_shortdescr">{{ ticket["AsstDoc.IntermedText"] || ticket["AsstDocItem.IntermedText"] || ticket.json }}</td>
</tr>
</tbody>
的onClick:
createInfoBox($event, index, ticket) {
this.renderer.selectRootElement(`#row_${index}`).insertAdjacentHTML('afterend', '<tr><td colspan="5">inserted content</td></tr>');
}
我还尝试了another approach,其中一个指令应该找到所有行并创建一个结果的QueryList,然后我可以从中检索所单击行的索引,并创建一个兄弟。查询列表空了。
@Directive({
selector: 'tr'
})
export class Rows {
constructor(public viewContainerRef: ViewContainerRef) { }
}
@ViewChildren(Rows) children: QueryList<Rows>;
ngAfterViewInit() {
console.log( this.children)
this.children.changes.subscribe((comps: QueryList <Rows>) =>
{
console.log("comps",comps);
});
}
我今天看到的所有例子让我感到困惑,在我的案例中,正确的做法是什么?
答案 0 :(得分:1)
您可以将tr包装在ng-template中,然后使用布尔+ ngIf渲染/取消渲染带有其他信息的新行
// component.html
<tbody>
<ng-container *ngFor="let ticket of tickets">
<tr (click)="createInfoBox(ticket)">
<td class="col-md-1">{{ ticket["AsstDoc.ProcState"] }}</td>
<td class="col-md-2">{{ ticket["AsstDoc.DocDate"] }}</td>
<td class="col-md-4">{{ ticket["AsstDoc.CustName"] }} {{ ticket["AsstDoc.DeliveryAddrNo"] || ticket["Addr.Line1"] }}</td>
<td class="col-md-4">{{ ticket["AsstDoc.IntermedText"] || ticket["AsstDocItem.IntermedText"] || ticket.json }}</td>
</tr>
<tr *ngIf="ticket.showAdditionalInfo">
<td colspan="5">inserted content</td>
</tr>
</ng-container>
</tbody>
//component.ts
createInfoBox(ticket) {
// toggle render of additional row
ticket.showAdditionalInfo = !ticket.showAdditionalInfo;
}
注意:如果要在新行打开时关闭所有打开的行,则需要额外的逻辑
答案 1 :(得分:1)
会像这样工作:
<ng-container *ngFor="let ticket of tickets; let i=index">
<tr class="row" (click)="updateInfoRow($event, i, ticket)" id="row_{{i}}">
<td class="col-md-1" id="ticket_state"> {{ ticket["AsstDoc.ProcState"] }} </td>
<td class="col-md-2" id="ticket_date">{{ ticket["AsstDoc.DocDate"] }}</td>
<td class="col-md-4" id="ticket_office">{{ ticket["AsstDoc.CustName"] }} {{ ticket["AsstDoc.DeliveryAddrNo"] || ticket["Addr.Line1"] }}</td>
<td class="col-md-4" id="ticket_shortdescr">{{ ticket["AsstDoc.IntermedText"] || ticket["AsstDocItem.IntermedText"] || ticket.json }}</td>
</tr>
<tr class="info-row">
<td>{{infoRows[i].SomeField</td>
... more tds ...
</tr>
</ng-container>
在组件中:
infoRows = [];
ngOnInit() {
for(int i = 0; i < tickets.length; i++){
infoRows.push({});
}
}
updateInfoRow(event, i, ticket) {
infoRow[i] = { myField, ticket.myField } // or set from the server
}
所以所有行都在那里。您可以隐藏它们,或者*它们,以便它们不会显示,直到点击为止。然后在一个幕后数组中填充数据,您可以根据索引在tr中绑定它。