Я новичок в angular 2+. Я создал таблицу в angular web api. Мне нужно сделать это так - когда я нажимаю кнопку (значок), расширяйте таблицу данными из моего веб-api. Я так и сделал, но это не работает. Может ли кто-нибудь помочь мне с решением?
app.component.html
<div class = "card-body">
<table datatable class = "table table-striped table-bordered hover" [dtOptions] = "dtOptions" style = "width:100%">
<thead>
<tr>
<th width = "2%" class = "text-center"></th>
<th width = "8%" class = "text-center">Name</th>
<th width = "8%" class = "text-center">Price</th>
</tr>
</thead>
<tbody>
<tr *ngIf = "empty">
<td colspan = "8" class = "text-center" translate>shared.table.not-found</td>
</tr>
<tr *ngFor = "let product of products; index as i" (click) = "onSelectLine(i)"
[ngClass] = "{'tr-selected': selectedIndex === i}">
<td class = "text-left">
<a type = "button" (click) = "onProductComponent(product)">
<i class = "fa fa-chevron-right"></i>
</a>
</td>
<td class = "text-left">{{product.name}}</td>
<td class = "text-left">{{product.price}}</td>
</tr>
<thead>
<tr>
<td colspan = "12" >
<div *ngIf = "isShown" class = "row container-fluid" id = "divshow" >
<td class = "text-left">{{product.name}}</td>
<td class = "text-left">{{product.price}}</td>
</div>
</td>
</tr>
</thead>
</tbody>
</table>
</div>
</div>
app.component.ts
isShown = false;
onProductComponent(product: Product) {
this.isShown = ! this.isShown;
this._product = product;
this.productComponentService.getProduct(this._product.id)
.subscribe(element => {
});
}
Это было бы так



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете добавить свойство isShown к каждому продукту. И измените только это значение.
Если вы хотите открыть несколько строк, просто удалите часть this.products.map() из onProductComponent.
public products = [
{ name: "Product 1", price: 101, isShown: false },
{ name: "Product 2", price: 102, isShown: false },
{ name: "Product 2", price: 103, isShown: false },
{ name: "Product 3", price: 104, isShown: false },
{ name: "Product 5", price: 105, isShown: false }
];
onProductComponent(product) {
this.products.map(p => {
if (product !== p) {
p.isShown = false;
}
});
product.isShown = !product.isShown;
}
Это приведет к изменению HTML, потому что вы можете переместить скрытый раздел внутри цикла. Потому что вам не нужно сохранять product.
<div class = "card-body">
<table datatable class = "table table-striped table-bordered hover" style = "width:100%">
<thead>
<tr>
<th width = "2%" class = "text-center"></th>
<th width = "8%" class = "text-center">Name</th>
<th width = "8%" class = "text-center">Price</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor = "let product of products; index as i">
<tr>
<td class = "text-left">
<a type = "button" (click) = "onProductComponent(product)">
<i class = "fa fa-chevron-right"></i>
Open
</a>
</td>
<td class = "text-left">{{product.name}}</td>
<td class = "text-left">{{product.price}}</td>
</tr>
<thead>
<tr>
<td colspan = "12">
<div *ngIf = "product.isShown" class = "row container-fluid" id = "divshow">
<span class = "text-left">{{product.name}}</span>
<span class = "text-left">{{product.price}}</span>
</div>
</td>
</tr>
</thead>
</ng-container>
</tbody>
</table>
</div>
Вы можете проверить рабочий пример здесь
Я не мог заставить его работать. По той причине, что в первом ngfor он указывает тип объекта продукта. (Продукт) И в раскрывающемся списке есть другой тип продукта (ProductComponent) Разве не нужно было бы создавать еще один ngFor?