Angular4 - 3级自定义组件,孙子(ngModelChange)始终看到相同的祖父母

时间:2017-11-19 23:12:49

标签: angular components onchange

我在模板中有一个顶级组件:

  <cw-card-list [cards]="cards">
  </cw-card-list>

当组件加载时,将从API填充卡片:

  private getCards(): void{
    this._cardService.getCards().subscribe(
      result => {
        this.cards = result;
      }
    );
  }

卡列表组件非常基本:

  <div *ngFor="let card of cards; let i = index">
    <cw-card-list-item
      [card]="card" [index]="i">
    </cw-card-list-item>
  </div>

您可以看到列表中的每张卡都是card-list-item子中的输入:

export class CardListItemComponent implements OnInit, AfterViewInit {
  @Input() card: Card;
  @Input() index: number;
...

最后,这些列表项组件中的每一个都有一个子项:

<cw-checklist-show [template]="card.template" 
</cw-checklist-show>

export class ChecklistShowComponent implements OnInit {
  @Input() template: Template
...

一切正常,所有数据都会显示出来。

然而,在最后一个组件中有一个复选框,它被绑定到一个属性&#39; is_completed&#39;每个孩子(一个TemplateItem):

<div *ngFor="let child of template.template_items; let i=index">
          <input id="checkbox-{{i}}" type="checkbox" 
            [ngModel]="child.is_completed"
            (ngModelChange)="onItemIsCompletedChange(i)">
</div>

每当(ngModelChange)事件触发时,它总是会修改&#39; is_completed&#39;列表中第一张卡的模板属性,而不是单击的模板。

为什么会这样?我甚至尝试将输出事件连接到父级并且控制台记录了模板 - 它总是在卡列表数组中列出相同的模板,项目[0]!

但如果我在祖父母中安装了console.log this.cards,它会显示每张卡上附有正确的模板!

数据结构

每张卡都有一个模板,如下所示:

import { Template } from './template';
export class Card {
  constructor() {
  }

  public id: string
  public customer_id: string
  public template: Template
  public follow_up: Date
  public is_new: boolean = true
}

每个模板都有一个TemplateItem数组:

import { TemplateItem } from './template-item';

export class Template {
  constructor(
  ) {}

  public id: string
  public account_id: string
  public name: string
  public template_items: Array<TemplateItem>
  public template_type: string
  public status: string
}

每个TemplateItem都是这样的:

export class TemplateItem {
  constructor(
  ) {}

  public id: string
  public template_id: string
  public sort: number
  public content: string
  public item_type: string
  public is_completed: boolean = false
}

1 个答案:

答案 0 :(得分:0)

如果您习惯于像我一样构建模型驱动表单,这可能不是很明显,但输入的ID非常重要。

由于我的输入使用了INDEX,这意味着我页面上的复选框没有不同的ID:

checkbox-{{i}}

这意味着单击它总是在第一张卡的复选框上触发事件(例如checkbox-0,checkbox-1),因为显然每个孙子(TemplateItem)都是0 ... n的数组。

所以解决方案是:

      <input id="checkbox-{{child.id}}-{{i}}" type="checkbox" 
        [ngModel]="child.is_completed"
        (ngModelChange)="onItemIsCompletedChange(i)">

现在每个复选框都有一个唯一的id,特定于孙子TemplateItem的id。