AngularJS 使用$timeout给出未定义的错误

AngularJS Using $timeout giving undefined error

本文关键字:未定义 错误 使用 timeout AngularJS      更新时间:2023-09-26

我试图制作这些记忆游戏之一,您需要翻转 2 张卡片并尝试匹配另一侧的图像,否则它们都会翻回来。

我的代码工作正常,除了如果没有匹配,我需要在 2 张卡被翻转回来之前添加延迟/暂停。我正在尝试使用$timeout,但收到错误:TypeError: Cannot set property 'isFlipped' of undefined

.HTML

<body ng-controller="MainCtrl as main">
<figure ng-class="{true: 'flipped', false: 'not-flipped'}[card.isFlipped]" class="card" 
        ng-repeat="card in cards" ng-click="flipCard(card.id, card.pair)">
  <img ng-src="img/cardback1.png" class="back"></img>
  <img ng-src="{{card.img}}" class="front"></img>
</figure>
</body>

我的控制

angular.module('CardApp').controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
  $scope.cards = [
    {
      img: 'img/chantal1.jpg',
      id: 1,
      isFlipped: false,
      pair: 1,
      matched: false,
    },
    {
      img: 'img/chantal1.jpg',
      id: 2,
      isFlipped: false,
      pair: 1,
      matched: false,
    },
    {
      img: 'img/chantal2.jpg',
      id: 3,
      isFlipped: false,
      pair: 2,
      matched: false,
    },
    {
      img: 'img/chantal2.jpg',
      id: 4,
      isFlipped: false,
      pair: 2,
      matched: false,
    },
    {
      img: 'img/chantal3.jpg',
      id: 5,
      isFlipped: false,
      pair: 3,
      matched: false,
    },
    {
      img: 'img/chantal3.jpg',
      id: 6,
      isFlipped: false,
      pair: 3,
      matched: false,
    },
    ];
  $scope.unflipCards = function(k, i) {
    $scope.cards[k].isFlipped = false;
    $scope.cards[i].isFlipped = false;
  };
  $scope.flipCard = function(id, pair) {
    var cards = $scope.cards;
    for(var i = 0, j = cards.length; i < j; i++) {
      // find card id in cards that is not matched
      if(cards[i].id == id && cards[i].matched == false) {
        // flip card
        cards[i].isFlipped = !cards[i].isFlipped;
        // check if any other cards are flipped
        for(var k = 0, j; k < j; k++) {
          // if we find another card that is flipped and is not yet matched
          if(cards[k].isFlipped == true && cards[k].matched == false && cards[k].id != id) {
            // check if this card is a pair with the current card
            if(cards[k].pair == pair) {
              // set matched to true
              cards[k].matched = true;
              cards[i].matched = true;
            } else {
              $timeout(function(){$scope.unflipCards(k, i)}, 1000); // undefined error
              //$scope.unflipCards(k, i); // works
            }
          }
        }
      }
    }
  };

}]);

我现在将尝试在 JSFiddle 中重新生成

在循环结束时,ki 已经比最后一个牌索引高出一个。因此,$scope.cards[k]$scope.cards[i]都不存在,因此是未定义的。

你可以做这样的事情:

$scope.unflipCardsTimeout = function(k, i) {
    $timeout(function(){$scope.unflipCards(k, i)}, 1000);
};

并在循环中替换:

$timeout(function(){$scope.unflipCards(k, i)}, 1000);

跟:

$scope.unflipCardsTimeout(k, i);

发生此错误是因为 k 和 i 未定义。您可以通过从

$timeout(function(){$scope.unflipCards(k, i)}, 1000);

$timeout(function(){var x=k;var y=i;$scope.unflipCards(x, y)}, 1000);

供参考 - http://plnkr.co/edit/o1namfsvFZbWlffmQsvd?p=preview

虽然我不知道$timeout不起作用的原因,但我建议通过传递卡片对象本身而不是其属性来简化整个代码。

ng-click='flipCard(card)'
$scope.flipCard = function(card) {
    if (card.matched) return;
    card.isFlipped = true;
    var cards = $scope.cards;
    for (var i=0; i<cards.length; i++) {
         var card2 = cards[i];
         // skip if it is self
         if (card2 == card) continue;
         // check if any other cards are flipped
         if (card2.isFlipped) {
             if (card.pair == card2.pair) {
                 card.matched = card2.matched = true;
             }
             else {
                 $timeout(function(){
                     card.isFlipped = card2.isFlipped = false;
                 }, 1000);
             }
             break;
         }
    }
}

这里的$timeoutfor loop完成后执行timeout因为该函数将在下一个摘要周期中调用。 所以在这一点上没有ki存在,所以它们是undefined.