英文:
How to stop rendering of an item if it has already been iterated - ngFor, ngIf, Angular 16
问题
我有一个对象数组,需要迭代并在表格中呈现一些数据(rafale和原材料、半成品和成品零件的数量)。
我的对象数组如下所示:
tableMongoData = [
{
ref: '322416730R',
type: 'RAW',
rafale: [
{
name: '14x63',
refs: [
{
type: 'PB',
ref: '8201729087',
partQty: '1.502',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729088',
partQty: '921',
rowspan: 1,
},
{
type: 'PA',
ref: '322419484R',
partQty: '112',
rowspan: 1,
},
],
},
{
name: '14x69',
refs: [
{
type: 'PB',
ref: '8201729081',
partQty: '761',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729083',
partQty: '295',
rowspan: 1,
},
{
type: 'PA',
ref: '322410929R',
partQty: '868',
rowspan: 1,
},
],
},
],
partQty: '1.467',
rowspan: 2,
},
{
ref: '322419487R',
type: 'RAW',
rafale: [
{
name: '15x58',
refs: [
{
type: 'PB',
ref: '8201729084',
partQty: '2.977',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729085',
partQty: '2.627',
rowspan: 1,
},
{
type: 'PA',
ref: '322414657R',
partQty: '397',
rowspan: 1,
},
],
},
],
partQty: '7.555',
rowspan: 1,
},
];
我的HTML文件如下:
<div class="container">
<table class="table table-responsive mt-5 caption-top">
<caption></caption>
<thead class="align-middle table-group-divider">
<tr>
<th class="text-center" scope="col">IDENTIFICAÇÃO PEÇA</th>
<th class="text-center" scope="col">PEÇA EM BRUTO</th>
<th class="text-center" scope="col">PEÇA BRANCA</th>
<th class="text-center" scope="col">PEÇA NEGRA</th>
<th class="text-center" scope="col">PEÇA ACABADA</th>
</tr>
</thead>
<tbody class="table-group-divider">
<ng-container *ngFor="let refRaw of tableMongoData">
<tr *ngFor="let rafale of refRaw.rafale">
<th class="text-center" scope="row">{{ rafale.name }}</th>
<td
[attr.rowspan]="refRaw.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="Referência: "
>
{{ refRaw.partQty }}
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
我的问题是第一个RAW引用的数量被呈现两次(图片中的表格)。
我认为这与我在
有没有办法停止迭代,知道第一个引用已经被迭代并且其数量已经被呈现?
我已经尝试使用*ngIf来检查引用是否已经被迭代,以及trackBy功能,但没有成功。我的代码实现方式可能有问题。
英文:
I have an array of objects which i have to iterate through and present some data (rafale and quantities of raw, semi-finished and finished parts) in the table.
My array of objects is as follows:
tableMongoData = [
{
ref: '322416730R',
type: 'RAW',
rafale: [
{
name: '14x63',
refs: [
{
type: 'PB',
ref: '8201729087',
partQty: '1.502',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729088',
partQty: '921',
rowspan: 1,
},
{
type: 'PA',
ref: '322419484R',
partQty: '112',
rowspan: 1,
},
],
},
{
name: '14x69',
refs: [
{
type: 'PB',
ref: '8201729081',
partQty: '761',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729083',
partQty: '295',
rowspan: 1,
},
{
type: 'PA',
ref: '322410929R',
partQty: '868',
rowspan: 1,
},
],
},
],
partQty: '1.467',
rowspan: 2,
},
{
ref: '322419487R',
type: 'RAW',
rafale: [
{
name: '15x58',
refs: [
{
type: 'PB',
ref: '8201729084',
partQty: '2.977',
rowspan: 1,
},
{
type: 'PN',
ref: '8201729085',
partQty: '2.627',
rowspan: 1,
},
{
type: 'PA',
ref: '322414657R',
partQty: '397',
rowspan: 1,
},
],
},
],
partQty: '7.555',
rowspan: 1,
},
];
My HTML file is as follows:
<div class="container">
<table class="table table-responsive mt-5 caption-top">
<caption></caption>
<thead class="align-middle table-group-divider">
<tr>
<th class="text-center" scope="col">IDENTIFICAÇÃO PEÇA</th>
<th class="text-center" scope="col">PEÇA EM BRUTO</th>
<th class="text-center" scope="col">PEÇA BRANCA</th>
<th class="text-center" scope="col">PEÇA NEGRA</th>
<th class="text-center" scope="col">PEÇA ACABADA</th>
</tr>
</thead>
<tbody class="table-group-divider">
<ng-container *ngFor="let refRaw of tableMongoData">
<tr *ngFor="let rafale of refRaw.rafale">
<th class="text-center" scope="row">{{ rafale.name }}</th>
<td
[attr.rowspan]="refRaw.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="Referência: "
>
{{ refRaw.partQty }}
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
My problem is that the quantity of the first RAW reference is rendered twice (picture TABLE).
I think it has to do with the fact that in my *ngFor inside a <tr> i iterate through 3 rafale references, thus a <td> inside that <tr> is rendered 3 times.
Is there any way of stopping iteration knowing that the first reference has already been iterated and its quantity has already been rendered?
I've already tried to use *ngIf in order to check whether the reference has already been iterated, and trackBy functionality but without success. There must be something wrong with the way i implement the code.
答案1
得分: 0
看起来你的数据模型有问题。如果你希望以简单的方式处理它,将qty和rowspan移到你的rafale项目中,如果没有属性,则不显示它。
以下是一个可工作的示例:
tableMongoData = [
{
ref: '322416730R',
type: 'RAW',
rafale: [
{
name: '14x63',
partQty: '1.467',
rowspan: 2,
refs: [
{ type: 'PB', ref: '8201729087', partQty: '1.502', rowspan: 1 },
{ type: 'PN', ref: '8201729088', partQty: '921', rowspan: 1 },
{ type: 'PA', ref: '322419484R', partQty: '112', rowspan: 1 },
],
},
{
name: '14x69',
refs: [
{ type: 'PB', ref: '8201729081', partQty: '761', rowspan: 1 },
{ type: 'PN', ref: '8201729083', partQty: '295', rowspan: 1 },
{ type: 'PA', ref: '322410929R', partQty: '868', rowspan: 1 },
],
},
],
},
{
ref: '322419487R',
type: 'RAW',
rafale: [
{
name: '15x58',
partQty: '7.555',
rowspan: 1,
refs: [
{ type: 'PB', ref: '8201729084', partQty: '2.977', rowspan: 1 },
{ type: 'PN', ref: '8201729085', partQty: '2.627', rowspan: 1 },
{ type: 'PA', ref: '322414657R', partQty: '397', rowspan: 1 },
],
},
],
},
];
英文:
It looks to me that your data model is to blame. If you wish to make it in a simple fashion, move your qty and rowspan to your rafale item, and if there's no property, don't display it.
Here is a working example :
tableMongoData = [
{
ref: '322416730R',
type: 'RAW',
rafale: [
{
name: '14x63',
partQty: '1.467',
rowspan: 2,
refs: [
{ type: 'PB', ref: '8201729087', partQty: '1.502', rowspan: 1 },
{ type: 'PN', ref: '8201729088', partQty: '921', rowspan: 1 },
{ type: 'PA', ref: '322419484R', partQty: '112', rowspan: 1 },
],
},
{
name: '14x69',
refs: [
{ type: 'PB', ref: '8201729081', partQty: '761', rowspan: 1 },
{ type: 'PN', ref: '8201729083', partQty: '295', rowspan: 1 },
{ type: 'PA', ref: '322410929R', partQty: '868', rowspan: 1 },
],
},
],
},
{
ref: '322419487R',
type: 'RAW',
rafale: [
{
name: '15x58',
partQty: '7.555',
rowspan: 1,
refs: [
{ type: 'PB', ref: '8201729084', partQty: '2.977', rowspan: 1 },
{ type: 'PN', ref: '8201729085', partQty: '2.627', rowspan: 1 },
{ type: 'PA', ref: '322414657R', partQty: '397', rowspan: 1 },
],
},
],
},
];
答案2
得分: 0
这将在打印数量之前修复问题,您可以使用索引来检查迭代次数,如果迭代不是第一次,则停止打印数量。以下是示例代码和演示:
<div class="container">
<h2>库存</h2>
</div>
<div class="container">
<table class="table table-responsive mt-5 caption-top">
<caption></caption>
<thead class="align-middle table-group-divider">
<tr>
<th class="text-center" scope="col">零件标识</th>
<th class="text-center" scope="col">原始零件</th>
<th class="text-center" scope="col">白色零件</th>
<th class="text-center" scope="col">黑色零件</th>
<th class="text-center" scope="col">完成零件</th>
</tr>
</thead>
<tbody class="table-group-divider">
<ng-container *ngFor="let refRaw of tableMongoData">
<tr *ngFor="let rafale of refRaw.rafale; let i = index">
<th class="text-center" scope="row">{{ refRaw.rafale[0].name }}</th>
<td
[attr.rowspan]="refRaw.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="参考: "
>
{{ i <= 0 ? refRaw.partQty : '' }}
</td>
<!-- <ng-container *ngFor="let rafale of refRaw.rafale">
<ng-container *ngFor="let ref of rafale.refs">
<td
[attr.rowspan]="ref.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="参考: "
>
{{ ref.partQty }}
</td>
</ng-container>
</ng-container> -->
</tr>
</ng-container>
</tbody>
</table>
</div>
[1]: https://stackblitz.com/edit/angular-ivy-ay6dxk?file=src%2Fapp%2Fapp.component.html
英文:
This will fix the issue before printing the qty you can check the iteration number using the index if iteration is not the first then stop printing the quantity. Here is the example code and working demo
<div class="container">
<h2>Stock</h2>
</div>
<div class="container">
<table class="table table-responsive mt-5 caption-top">
<caption></caption>
<thead class="align-middle table-group-divider">
<tr>
<th class="text-center" scope="col">IDENTIFICAÇÃO PEÇA</th>
<th class="text-center" scope="col">PEÇA EM BRUTO</th>
<th class="text-center" scope="col">PEÇA BRANCA</th>
<th class="text-center" scope="col">PEÇA NEGRA</th>
<th class="text-center" scope="col">PEÇA ACABADA</th>
</tr>
</thead>
<tbody class="table-group-divider">
<ng-container *ngFor="let refRaw of tableMongoData">
<tr *ngFor="let rafale of refRaw.rafale; let i = index" >
<th class="text-center" scope="row">{{ refRaw.rafale[0].name }}</th>
<td
[attr.rowspan]="refRaw.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="Referência: "
>
{{ i <= 0 ? refRaw.partQty : '' }}
</td>
<!-- <ng-container *ngFor="let rafale of refRaw.rafale">
<ng-container *ngFor="let ref of rafale.refs">
<td
[attr.rowspan]="ref.rowspan"
class="text-center align-middle"
tabindex="0"
data-html="true"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="Referência: "
>
{{ ref.partQty }}
</td>
</ng-container>
</ng-container> -->
</tr>
</ng-container>
</tbody>
</table>
</div>
答案3
得分: 0
以下是您要翻译的部分:
"Solution was inspired by the comment of Prabath Udayanga."
"如果我能够使用ngIf指令来定义是否要打印一个值,那么我应该能够使用ngIf指令来告诉表格何时创建数据单元格。"
"I made the following modification to code:"
"<td>标签中,我根据rafale的索引添加了一个条件:*ngIf="i === 0"。这意味着只有在rafale的第一个实例时才会创建单元格数据。"
"由于我总是至少有一个rafale标识,所以我总是为现有的rafale创建单元格数据。当我有多个rafale与零件参考相关时,我只创建一个单元格数据,rowspan属性会处理其余部分。"
"Working code is on the following link:"
"Working code"
英文:
Solution was inspired by the comment of Prabath Udayanga.
If I'm able to define whether I want to print a value or not, using *ngIf directive, I should be able, using *ngIf directive, to tell the table when to create a data cell.
I made the following modification to code:
<tbody class="table-group-divider">
<ng-container *ngFor="let refRaw of tableMongoData">
<tr *ngFor="let rafale of refRaw.rafale; let i = index">
<th class="text-center" scope="row">{{ rafale.name }}</th>
<td *ngIf="i === 0" [attr.rowspan]="refRaw.rowspan" class="text-center align-middle" tabindex="0"
data-html="true" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-title="Referência: ">
{{ refRaw.partQty }}</td>
<td *ngFor="let ref of rafale.refs" [attr.rowspan]="ref.rowspan" class="text-center align-middle"
tabindex="0" data-html="true" data-bs-toggle="tooltip" data-bs-placement="top"
data-bs-title="Referência: ">
{{ ref.partQty }}
</td>
</tr>
</ng-container>
</tbody>
In <td> tag I've added a condition based on an index of rafale: *ngIf="i === 0". This means that the cell data is created only for the first instance of the rafale.
Since I always have at least 1 rafale identifiction, I always create a cell data for an existing rafale.
When I have multiple rafales per part reference, I create only one cell data and rowspan attribute takes care of the rest.
Working code is on the following link:
Working code
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
- angular
- angular-ng-if
- html
- ngfor
- rendering
评论