【问题标题】:DOM not updating when click/tap event is executed using Ionic and Angular使用 Ionic 和 Angular 执行单击/点击事件时 DOM 未更新
【发布时间】:2019-08-20 19:59:48
【问题描述】:

我正在使用指令*ngFor 将离子卡组件从名为userData 的数组加载到DOM。 userData 数组由具有 id、title 和 count 属性的嵌套对象组成。

我正在尝试创建一个点击/点击事件,每当用户点击卡片时,计数就会增加被点击的特定卡片。

我遇到的问题是当我点击卡片时*ngFor 没有更新。但是当我只引用 *ngFor 指令之外的计数时,它确实有效。

我想使用*ngFor 指令并在我单击每张卡片时单独更新它们。任何帮助深表感谢。

Tally 组件 HTML 模板粘贴

<ion-card class="ion-card-custom" (click)="increaseCount()" *ngFor="let tal of userData">
       <ion-item>
           <ion-icon name="pin" slot="start" ></ion-icon>
           <ion-label>{{ tal.title }}</ion-label>
           <section class="tally-info-count" >{{ tal.count }} </section>
           <section class="tally-info-count" >{{ tap }} </section>
           <ion-button fill="outline" slot="end" class="info-button"> i </ion-button>
       </ion-item>
       <ion-item>
           <ion-label>{{ tal.created }} </ion-label>
           <p (click)="increaseCount()">{{ plus }} </p>
       </ion-item>
</ion-card>

<ion-card (tap)="tapEvent($event)">
    <ion-item>
      Tapped: {{tap}} times
    </ion-item>
  </ion-card>

完整的 Tally 组件粘贴

import { getLocaleDateTimeFormat } from '@angular/common';

//decorator
@Component({
    selector: 'app-tally',
    templateUrl: 'tally.html',
    styleUrls: ['tally.scss'],
  })

  export class Tally implements OnInit {
    title: string;
   public count: number = 0; 
   public tap: number = 0;
    plus: number; 
    userData: any[];
    id: number;
    //date created
    dateTime: Date = new Date();
    created: string = `${this.dateTime.getUTCMonth() +1}/${this.dateTime.getDay}/${this.dateTime.getUTCFullYear()}`

    constructor() { this.plus = 0;}

    ngOnInit() {
        this.title = "Title";
        this.userData = [
            {
                id: this.id,
                title: this.title,
                count: this.tap,
                created: this.created
            },
            {
                id: this.id,
                title: this.title,
                count: this.count,
                created: this.created
            }
        ]

    }

    increaseCount () {
        this.count += 1;
        this.plus += 1;
        console.log('this.count:', this.count);
    }

    tapEvent(e) {
        console.log(e);
        this.tap++;
      }
  }

【问题讨论】:

  • 这篇文章让我有点困惑..你能改写一下这个问题还是重申一下?
  • 是的。对不起,我会改写。
  • 我改写了它,但我还要在这里留下一个小得多的问题。我真正想做的基本上是每次点击或点击卡片时都会增加每张卡片。我希望每张卡片只有在被点击时才能增加,而不是任何其他卡片。我希望这有帮助。并提前感谢您!

标签: angular ionic-framework ionic4 angular8


【解决方案1】:

根据您的 cmets,您似乎没有更新正确的计数器。当您在模板中循环 userData 时,您需要更新它所引用的正确数据,而不是您创建的没有完成任何事情的额外属性。

首先,我们需要跟踪 ngFor 中的索引,以便我们知道要更新的用户

<ng-template *ngFor="let tal of userData; let i = index;">
<ion-card class="ion-card-custom" (click)="increaseCount(i)">
    <ion-item>
        <ion-icon name="pin" slot="start" ></ion-icon>
        <ion-label>{{ tal.title }}</ion-label>
        <section class="tally-info-count" >{{ tal.count }} </section>
        <section class="tally-info-count" >{{ tap }} </section>
        <ion-button fill="outline" slot="end" class="info-button"> i </ion-button>
    </ion-item>
    <ion-item>
        <ion-label>{{ tal.created }} </ion-label>
        <p> {{ plus }} </p>
    </ion-item>
</ion-card>

我已将索引添加到 ngFor,因此我们知道我们正在查看的用户的索引。另一个变化是我将 ngFor 放在了 ngTemplate 上。有时把它放在一个组件上会导致问题,所以我有时这样做只是为了安全。最后,我将索引传递给(click)="increaseCount(i)",这样我们就知道要更新哪个 userData。接下来我们需要更新您的组件代码并删除一些无用的数据。

import { getLocaleDateTimeFormat } from '@angular/common';

//decorator
@Component({
    selector: 'app-tally',
    templateUrl: 'tally.html',
    styleUrls: ['tally.scss'],
  })

export class Tally implements OnInit {
  userData: any[];

  constructor() { }

  ngOnInit() {
    const dateTime: Date = new Date();
    const created: string = `${dateTime.getUTCMonth() +1}/${dateTime.getDay}/${dateTime.getUTCFullYear()}`;
    this.userData = [
        {
            id: 0,
            title: "Title1",
            count: 0,
            created: created
        },
        {
            id: 1,
            title: "Title2",
            count: 0,
            created: created
        }
    ]

  }

  increaseCount (index: number) {
    const specificUserData = this.userData[index];
    specificUserData.count++;
  }
}

我删除了这些属性,因为它们没有用,因为数据需要存在于 userData 中。然后我使用从模板传入的索引来确定我们需要修改哪个 userData。还有其他方法可以做到这一点,但考虑到您的项目设置方式,这可能是最简单的方法。

【讨论】:

  • 谢谢大家!!我对 Angular 很陌生,我完全错误地处理了这个问题!
【解决方案2】:

您更新的是this.count,而不是tal.count

<ion-card class="ion-card-custom" (click)="increaseCount(tal)" *ngFor="let tal of userData">

increaseCount (tal: any) {
    tal.count += 1;
    ...
}

【讨论】:

    【解决方案3】:

    我发现您的代码中有两个谬误:

    1. increaseCount()tapEvent() 中分别增加this.countthis.tap。但this 在此上下文中指的是Component,而不是特定的用户/卡。因此,模板中的{{ tap }} 对于所有卡的值将是相同的,这就是为什么您的计数器“未单独更新”。

    2. 你初始化userData

    this.userData = [
        {
            id: this.id,
            title: this.title,
            count: this.tap,
            created: this.created
        },
        {
            id: this.id,
            title: this.title,
            count: this.count,
            created: this.created
        }
    ]
    

    this.tapthis.count分别初始化count属性,即0。

    但这所做的是将属性值绑定this.tapthis.count,即更改increaseCount()tapEvent()中的值影响userData项目的count属性。

    这就是为什么“当[您]点击卡片时*ngFor没有被更新”。

    为了在此处获得预期的行为,您需要将*ngFor 循环中的当前 tal 实例传递给increaseCount(),如下所示:

    <ion-card class="ion-card-custom" (click)="increaseCount(tal)" *ngFor="let tal of userData">
           ...
    </ion-card>
    

    而不是增加 Componentthis.count 您需要增加传递对象的 count 属性:

    increaseCount(tal) {
        tal.count++;
    }
    

    您也可以使用@Derek 建议的索引,而不是传递对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-21
      • 2015-11-24
      • 2019-11-28
      • 2019-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 1970-01-01
      相关资源
      最近更新 更多