【问题标题】:Issues with model bindings on Forms with several *ngFor具有多个 *ngFor 的表单上的模型绑定问题
【发布时间】:2017-05-28 21:34:33
【问题描述】:

我正在使用一个表格,其中重复了以下模型:

  • 我有一个选择,我可以选择我拥有的任何类型的Bottle
  • 我可以在其中为所选类型选择瓶子数量的输入。

对于 2 个 Bottle 数组(Bottle 类型由 IdName 组成)重复此模式,如下所示:

  • orderedBottles 的数组,用户可以在其中订购一些瓶子。
  • returnedBottles 的数组,用户可以在其中退回一些瓶子。

我希望能够在提交时选择任何类型的瓶子和相应的计数,但我相信我错过了一些东西,因为行为都搞砸了:

  • 两个数组的输入相互链接,
  • 当我更改选择中的某些选项时,有时会更新其他选择,这不是我想要的(显然)...

这是 plunkr 中的一个工作示例:http://plnkr.co/edit/1z6dN6?p=preview


这是我的 html 文件(我使用的是 AngularMaterial 2):

  <div fxLayout="row" style="max-width: 80%">

    <!-- ORDERED BOTTLES -->
    <div fxLayout="column" style="min-width: 50%">
      <div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of orderedBottles; let i = index">
        <md-select class="select" placeholder="Select bottle type" name="orderedTypeSelect_{{i}}" [(ngModel)]="orderedBottles[i].typeId">
          <md-option class="options" *ngFor="let type of orderedClonedArrayBottles" [value]="type.typeId">
            {{ type.name }}
          </md-option>
        </md-select>

        <md-input-container class="container">
          <input md-input type="number" name="orderedBottleInput_{{i}}" autocomplete="off" [(ngModel)]="orderedBottles[i].count"
          step="1" min="0" max="99">
        </md-input-container>

        <button class="button-row" type="button" (click)="removeRow(i, 'order')">-</button>
      </div>
    </div>

    <!-- RETURNED BOTTLES -->
    <div fxLayout="column" style="min-width: 50%">
      <div fxLayout="row" style="max-width: 100%" *ngFor="let bottle of returnedBottles; let j = index">
        <md-select class="select" placeholder="Select bottle type" name="returnedTypeSelect_{{j}}" [(ngModel)]="returnedBottles[j].typeId">
          <md-option class="options" *ngFor="let typed of returnedClonedArrayBottles" [value]="typed.typeId">
            {{ typed.name }}
          </md-option>
        </md-select>

        <md-input-container class="container">
          <input md-input type="number" name="returnedBottleInput_{{j}}" autocomplete="off" [(ngModel)]="returnedBottles[j].count"
          step="1" min="0" max="99">
        </md-input-container>

        <button class="button-row" type="button" (click)="removeRow(j, 'return')">-</button>
      </div>

    </div>
  </div>

添加一些解释,这是一个子组件,它有一个 Bottle 数组作为 @Input(),我将其克隆到 2 个不同的数组(orderedClonedArrayBottlesreturnedClonedArrayBottles)中,因此我的父数组不是t 从子更新中更新。

然后我用 orderedBottles 数组和 returnedBottles 显示我的瓶子,它们从预先克隆的 2 个中获取它们的值。

ngOnChanges(changes) {
    // Get @Input data when it's ready
    if (changes.bottleArray) {
      // Cloning
      //this.orderedClonedArrayBottles = [...changes.bottleArray.currentValue];
      //this.returnedClonedArrayBottles = [...changes.bottleArray.currentValue];

      this.orderedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);
      this.returnedClonedArrayBottles = Array.from(changes.bottleArray.currentValue as Bottle[]);

      console.log(this.orderedClonedArrayBottles);
      console.log(this.returnedClonedArrayBottles);

      // Display first rows
      if (this.orderedClonedArrayBottles.length > 0) {
        this.orderedBottles.push(this.orderedClonedArrayBottles[0]);
      }
      if (this.returnedClonedArrayBottles.length > 0) {
        this.returnedBottles.push(this.returnedClonedArrayBottles[0]);
      }
    }
  }

我不知道为什么它不能正常工作,很可能是因为我没有按我应该的方式管理*ngFor。我已经为*ngFor 看到过关于trackBy 的帖子,但我不知道这是否有帮助。

【问题讨论】:

    标签: angular binding angular2-forms ngfor


    【解决方案1】:

    您正在克隆bottleArray。但在你的情况下,瓶子对象没有被克隆。相同的引用被推送到两个数组中。

    检查这个answer

    您可能必须为每个瓶子对象使用Object.assign。 如果您有嵌套对象,则必须遍历属性并复制。

    【讨论】:

    • 工作完美。非常感谢!
    • 对于有需要的人:我在答案的链接中发布了我自己的 deepClone() 方法。
    猜你喜欢
    • 2020-04-28
    • 2017-06-20
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多