$ animate.addClass TypeError:无法读取undefined的属性'parentNode'

时间:2014-12-13 18:52:28

标签: javascript css angularjs animation

对于我的指令,我正在尝试使用动画服务:

$animate.addClass(clickedCard, "translate-to-player-spot-1", function () {
    alert('wooo!');
});

但是这会立即触发警报并且动画没有发生!我需要在动画结束时执行功能。

更新我将Angular版本更改为1.3.6,现在收到错误:

TypeError: Cannot read property 'parentNode' of undefined
    at http://192.168.0.102/CardGame/js/angular-animate.min.js:20:254
    at http://192.168.0.102/CardGame/js/angular-animate.min.js:8:69
    at k.$digest (http://192.168.0.102/CardGame/js/angular.min.js:124:43)
    at k.scopePrototype.$digest (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1468:23)
    at k.$apply (http://192.168.0.102/CardGame/js/angular.min.js:126:58)
    at k.scopePrototype.$apply (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1478:22)
    at HTMLDivElement.<anonymous> (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:797:25)
    at HTMLDivElement.c (http://192.168.0.102/CardGame/js/angular.min.js:32:285)

CSS看起来像:

.translate-to-player-spot-1 {
    transform: translate(0px,-270px);
    transition: transform 50s linear;
}

如果我将ng-class="card.moveTo"添加到HTML并在指令中设置:

clickedCard.moveTo = 'translate-to-player-spot-1'

然后它确实经历了动画并添加了各种角度类:

ng-animate translate-to-player-spot-1-add translate-to-player-spot-1 translate-to-player-spot-1-add-active

我有一种感觉,我不理解AngularJS中的动画 - 有人可以请一些亮点吗?

谢谢!

HTML:

<div id="{{card.id}}" ng-class="card.moveTo" class="card-wrap card-art card-art-{{card.back}} ready-to-move-{{card.readyToMove}}" ng-click="click()" ng-repeat="card in cardsCtrl.cards">
    <div ng-class="card.name" class="card-art">
        <div class="card"></div>
    </div>
</div>

相关指令:

app.directive('playerHandTemplate', function(PlayerHand, PlayerPlayed) {
    return {
        restrict: 'E',
        templateUrl: 'templates/card.html',
        scope:{},
        link: function(scope, element, $animate) {
            element.on('click', function() {
                scope.$apply(function() {
                    $animate.addClass(element, 'translate-to-player-spot-1');
            })});
        },
        controller: function($scope, $animate) {
            this.cards = PlayerHand.getHand();

            $scope.click = function() {
                var clickedCard = this.card;

                if (clickedCard.readyToMove === true) {
                    $animate.addClass(clickedCard, "translate-to-player-spot-1", function () {
                        alert('wooo!');
                    });
                } else {
                     PlayerHand.changeReadyToMove(clickedCard);
                }

            }

        },
        controllerAs: 'cardsCtrl'
    };
});

PlayerHand是一个服务,getHand()只返回一个对象数组。

1 个答案:

答案 0 :(得分:2)

您收到错误TypeError: Cannot read property 'parentNode' of undefined,因为在以下代码中clickedCard不是DOM元素:

$animate.addClass(clickedCard, "translate-to-player-spot-1", function () {
  alert('wooo!');
});

link功能中,您有以下内容:

element.on('click', function() {
  scope.$apply(function() {
    $animate.addClass(element, 'translate-to-player-spot-1');
  });
});

这不会按预期工作。

考虑以下呈现HTML的简化示例:

<player-hand-template>
  <card></card>
  <card></card>
  <card></card>
</player-hand-template>

传递给element函数的link将是player-hand-template,而不是一张卡。

您可以做的是以下内容:

将您的ng-click更改为以下内容:ng-click="click(card, $event)"

在你的控制器中:

$scope.click = function(card, event) {

  var clickedElement = event.currentTarget;
}

现在您可以访问表示卡片的对象和相关的DOM元素,例如可以:

$scope.click = function(card, event) {

  if (card.hasMoved) return;

  card.hasMoved = true;

  var clickedElement = event.currentTarget;

  var promise = $animate.addClass(clickedElement, 'translate-to-player-spot-1');

  promise.then(function() {
    console.log('Done.');
  });
};

如上所述,在Angular 1.3中,$animate.addClass不会将回调函数作为参数,而是返回一个promise。

演示: http://plnkr.co/edit/5Gf2ApyxEKgGQAs98IjG?p=preview

请注意,在这种情况下,您也可以将点击逻辑移动到link功能中。如果你真的应该移动或不移动它很难说没有看到完整的图片。通常在想要将API公开给其他指令时使用controller(因为它们可以注入控制器),否则你使用link