【问题标题】:Angular 2 click fired multiple times inside ngForAngular 2 click 在 ngFor 内多次触发
【发布时间】:2017-04-13 15:03:18
【问题描述】:

我的组件有一个非常奇怪的问题(以前从未见过)。单击 ngFor 列表中的按钮时,我试图删除一行。当我只有一行时它可以工作,但是当它超过一行时,事件会被触发两次,一次用于好行,一次用于第一行(删除另一行后):

<label>
    <div class="tag" *ngFor="let o of selectedOptions;">
        <span class="tag-text">{{ o.textContent }}</span>
        <button (click)="removeTag(o)" type="button" class="fa fa-times"></button>
    </div>
</label>

这是我的方法,女巫被调用了两次(仅当有多个“选项”时):

public removeTag (option: NxtSelectOptionComponent) {
    this.selectedOptions = [
        ...this.selectedOptions.filter(o => o !== option),
    ]
}

我尝试使用 splice,我尝试添加 stopPropagation...我不明白我已经做了很多时间,这是我第一次看到。

编辑:当我点击 .tag 元素时调用 removeTag 方法这就是为什么当我点击按钮时它被调用两次,但我不知道为什么...... (click) 属性是仅在按钮上

问题已解决:我找到了问题...仅供参考标签标签将点击按钮,因此如果您有任何(点击)属性,它将被触发两次。

【问题讨论】:

  • 你检查你的过滤功能了吗?这不是问题吗?您是否尝试在 removeTag() 函数中添加一些 console.log() 以查看它是否被调用了两次?也许你应该尝试在 removeTag 函数的末尾console.log(this.selectedOptions) 看看有什么改变。让我们知道是否有新的东西,因为现在它很奇怪。你的代码很好,所以...
  • 谢谢 我没有过滤功能。 removeTag 被调用两次。我发现即使我单击 .tag 元素也会调用它(女巫是为什么 removeTag 被调用两次)我不知道为什么,如果我单击 .tag 元素,目标(在事件对象内)是列表 o_O 的第一个按钮!
  • 你能在 Plunker 中重现吗?
  • 我发现了问题...仅供参考标签标签将点击按钮,因此如果您有任何(点击)属性,它将被触发两次。

标签: angular typescript


【解决方案1】:

实际上第二次点击会被父元素调用。 浏览器的默认行为是,一旦父级被点击,就会触发对输入的点击。

使用

event.preventDefault();

停止第二次触发。

【讨论】:

    【解决方案2】:

    完整解决方案:

    <label>
        <div class="tag" *ngFor="let o of selectedOptions;">
            <span class="tag-text">{{ o.textContent }}</span>
            <button (click)="removeTag(o, $event)" type="button" class="fa fa-times"></button>
        </div>
    </label>
    

    然后是接受事件的方法:

    public removeTag (option: NxtSelectOptionComponent, event) {
        event.preventDefault(); // This is needed to prevent the click event from firing twice on a label
        this.selectedOptions = [
            ...this.selectedOptions.filter(o => o !== option),
        ]
    }
    

    【讨论】:

      【解决方案3】:

      值得一提我的情况,以防它绊倒其他人。包含按钮的组件订阅了一个 observable 并且永远不会取消订阅,因此这使旧组件保持活动状态并触发它们的单击方法。确保 .unsubscribe() 您在按钮的父组件中创建的任何订阅。

      【讨论】:

      • 感谢您的评论。它让我想到了解决问题的正确方向。
      【解决方案4】:

      试试这个

      <div *ngFor="let user of users; let i=index" >
          {{user.name}}
          <div>
              <a class="btn btn-danger" (click)="removeUser(i)">-</a>
          </div>
      </div>
      
      removeUser(i): void {
          this.users.splice(i, 1);
      }
      

      【讨论】:

      • 感谢您的回复,我已经尝试使用 splice 按索引删除,但我遇到了同样的问题... :(
      • 在这种情况下还有其他问题,这对我有用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2017-10-03
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多