Angular 角度8-删除时材料表未显示正确数据

Angular 角度8-删除时材料表未显示正确数据,angular,angular-material,Angular,Angular Material,我有一个材质表,以选择的形式显示可用选项 我有一个根对象,它是ngModel,用于保留选项 这些选项是从数据库中检索的 假设我有一个菜单的根项。这将在一个名为“零食”的数组中跟踪饮料和水果,如下所示: this.menu = { id: 1, snacks: [ { fruitId: 1, drinkId: 1, deleted: false }, { fruitId: 2, drinkId: 2, deleted: false }, {

我有一个材质表,以选择的形式显示可用选项

我有一个根对象,它是ngModel,用于保留选项

这些选项是从数据库中检索的

假设我有一个
菜单的根项。这将在一个名为“零食”的数组中跟踪饮料和水果,如下所示:

this.menu =
  {
    id: 1,
    snacks: [
      { fruitId: 1, drinkId: 1, deleted: false },
      { fruitId: 2, drinkId: 2, deleted: false },
      { fruitId: 3, drinkId: 2, deleted: false },
      { fruitId: 3, drinkId: 2, deleted: true },
    ]
  };
然后我们定义了一些用户可以选择的水果和饮料:

this.fruits = [
  { id: 1, name: "Orange" },
  { id: 2, name: "Apple" },
  { id: 3, name: "Banana" },
  { id: 4, name: "Dragon fruit" }
];
this.drinks = [
  { id: 1, name: "Milk" },
  { id: 2, name: "Water" },
  { id: 3, name: "Juice" },
  { id: 4, name: "Soda" }
];
然后,我们在表中映射这些:

<table mat-table [dataSource]="menuTableSource" #menuTable>

                        <ng-container matColumnDef="fruit">
                            <th mat-header-cell *matHeaderCellDef> Fruit </th>
                            <td mat-cell *matCellDef="let menuItem; let i = index;">
                                <mat-select [(ngModel)]="menu.snacks[i].fruitId" name="fruitId"
                                    #fruitId="ngModel">
                                    <mat-option *ngFor="let fruit of fruits" [value]="fruit.id">
                                        {{ fruit.name }}
                                    </mat-option>
                                </mat-select>
                            </td>
                        </ng-container>

                        <ng-container matColumnDef="drink">
                            <th mat-header-cell *matHeaderCellDef> Drink </th>
                            <td mat-cell *matCellDef="let menuItem; let i = index;">
                                <mat-select [(ngModel)]="menu.snacks[i].drinkId"
                                    name="drinkId" required>
                                    <mat-option *ngFor="let drink of drinks" [value]="drink.id">
                                        {{drink.name}}
                                    </mat-option>
                                </mat-select>
                            </td>
                        </ng-container>

                    <tr mat-header-row *matHeaderRowDef="menuTableColumns"></tr>
                    <tr mat-row *matRowDef="let row; columns: menuTableColumns;"></tr>
</table>
这是一个bug还是我必须以其他方式更新表

请参阅此stackblitz,它演示了ISsue:

更新版: 再次查看代码之后。我意识到,您正在删除右边的行,数据更新很好,但由于您正在显示
fruits
中的select下拉列表项,这给您带来了混乱

<ng-container matColumnDef="fruit">
  <th mat-header-cell *matHeaderCellDef> Fruit </th>
  <td mat-cell *matCellDef="let menuItem; let i = index;">
<mat-select [(ngModel)]="menu.snacks[i].fruitId" name="fruitId"
#fruitId="ngModel">
<mat-option *ngFor="let fruit of fruits" [value]="fruit.id">
  {{ fruit.name }}
</mat-option>
</mat-select>
</td>
</ng-container>

如果您不想删除该项目,您可以稍后删除该项目的属性,但只需为其他进程添加已删除的属性。

再次查看该问题,我意识到我可能有点傻

麦翰给我指出了正确的方向

当然,绑定到ngModel不起作用,因为ngModel在未过滤的集合上运行

但由于我想保留对已删除项目的引用,我添加了一个新数组

deletedSnacks = [];
在我的removeMenuItem函数中,我将零食推入该数组,拼接它们,然后在提交到后端时,我只需将它们合并

onRemoveMenuItem(menuItem: any): void {
const idx = this.menu.snacks.indexOf(menuItem);
if (idx >= 0) {
  this.menu.snacks[idx].deleted = true;
  this.deletedSnacks.push(this.menu.snacks[idx]);
  this.menu.snacks.splice(idx, 1);
  this.menuTableSource.data = this.menu.snacks;
  this.menuTable.renderRows();
  }
}

在更新数据时,没有办法过滤掉已删除的项目(并将其保留在收藏中)?@HenrikM你做得绝对正确。您只需要查看数据结构。代码正在按预期工作。“如果删除第一项,第二项将再次在选择列表中显示橙色,因为这一点”-为什么选择显示该值,因为它不再是数据源数据的一部分?
onRemoveMenuItem(i): void {
  this.menu.snacks.splice(i, 1);
  this.menuTableSource.data = this.menu.snacks;
  this.menuTable.renderRows();
}
deletedSnacks = [];
onRemoveMenuItem(menuItem: any): void {
const idx = this.menu.snacks.indexOf(menuItem);
if (idx >= 0) {
  this.menu.snacks[idx].deleted = true;
  this.deletedSnacks.push(this.menu.snacks[idx]);
  this.menu.snacks.splice(idx, 1);
  this.menuTableSource.data = this.menu.snacks;
  this.menuTable.renderRows();
  }
}