javascript - ng-repeat 中的按钮每秒更改 10 次,导致其不可点击

标签 javascript html angularjs angularjs-ng-repeat angularjs-ng-click

描述

我有一个网页的一部分,显示每个团队的名称和得分,每个团队有两个按钮(得分 -1 和得分 +1)。 enter image description here

Teams 是一个数组,团队使用 ng-repeat 显示。

    <!-- Teams Info & Control -->
    <div class="row center-text" style="height: 40%;">
      <div class="col" ng-repeat="team in game.teams">
        <h5 style="display: inline;">{{team.name}}</h5>
        <i class="fa fa-edit" ng-click="editTeamName($index)" class="btn btn-link"></i>
        <h6>{{team.score}}</h6>
        <div class="row">
          <div class="col">
            <button type="button" ng-click="scoreChange($index, -1)" class="btn btn-primary fill-height fill-width">Score -1</button>
          </div>
          <div class="col">
            <button type="button" ng-click="scoreChange($index, 1)" class="btn btn-primary fill-height fill-width">Score +1</button>
          </div>
        </div>
      </div>
    </div>

teams 数组是一个名为“game”的较大对象的一部分,该对象每秒从 socket.io 服务器接收 10 次。每秒需要10次,因为游戏对象中有一个计时器,需要高精度地显示给用户。

游戏对象如何在客户端更新:

socket.on('gameUpdate', function(game) {
  $scope.$apply(function() {
    $scope.game = game
  });
});

示例游戏对象:

{
  gameRunning: false,
  shotClockTime: defaultFullShotClock, //Value changing 10 times per second other values may change too but not as frequently
  oldShotClockValue: defaultFullShotClock,
  teams: [{
    name: "White",
    score: 0
  }, {
    name: "Blue",
    score: 0
  }],
  inOvertime: false,
  currentPeriod: 0,
  periods: {
    mainGame: generateMainGame(defaultPeriodTime, defaultBreakTime, defaultHalfTime),
    overtime: generateOverTime(defaultOverTimePeriodTime, defaultBreakTime)
  }
}

我认为问题所在

当游戏对象更改时,即使团队数组本身没有发生任何更改,团队也会显示 HTML 已更新 ($$!)。问题在于,鼠标按下然后鼠标松开事件通常需要超过 0.1 秒的时间,这意味着它们不会发生在同一个按钮上,因此它们不会注册为单击,这意味着 ng-click 不会被调用。

$$! (我认为发生这种情况是因为在检查元素中该部分闪烁紫色。此外,当鼠标悬停在按钮上时,按钮颜色会在悬停颜色和默认颜色之间快速交替。Video)

可能的解决方案

  1. 让 angular-js 意识到没有任何改变,因此它不会改变 HTML,这意味着一切都会好起来(不知道如何做到这一点,但如果你这样做,那么这可能是一个解决方案)
  2. 让按钮保持不变,因为它们永远不会根据团队数组的情况而改变(除非它变得更大意味着有更多的按钮)
  3. 不要使用 ng-repeat 复制和粘贴代码,因为应该始终有两个团队(这是最后的解决方案,因为我将来可能需要添加更多团队及其“糟糕”代码)

最佳答案

在 ng-repeat 中使用 track by 子句,例如:

<div class="col" ng-repeat="team in game.teams track by $index">
Track by 是一个有用的子句,它可以做一些事情,但其中之一是它让 Angular 跟踪列表中的哪些项目,以便它知道哪些项目需要重新渲染或哪些项目已经存在。但是,如果这些项目来自数据库并且具有唯一标识符,那么实际上最好使用该属性作为跟踪器而不是索引,因为它性能更好并且允许重新排序:

<div class="col" ng-repeat="team in game.teams track by team.id">

文档: https://docs.angularjs.org/api/ng/directive/ngRepeat

关于javascript - ng-repeat 中的按钮每秒更改 10 次,导致其不可点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47126863/

相关文章:

javascript - 使用 angularjs $resource 从 Web api 调用自定义方法

javascript - "Array to string conversion error"尝试获取字段值时

javascript - 防止将事件类添加到 fullpage.js 的部分

javascript - 如何使此 hta 仅在提交值后创建文本文件

javascript - 预加载内容与 Ad-Hoc

css - Bootstrap 缩略图填充

javascript - 解决延迟不按预期工作

css - 使用 CSS 在 SharePoint 2013 的 TopBar 导航中并排(彼此相邻)的 DIV

unit-testing - 如何模拟指令以启用更高级别指令的单元测试?

javascript - 无法通过单击按钮向上滚动到菜单顶部 - AngularJS