简体   繁体   English

在ng-repeat内部使用AngularJS设置动画

[英]Animating a button with AngularJS inside ng-repeat

I have this online shop here that is displaying items, sizes, prices, etc. and I want to add an animation to the .add-to-cart-btn <button> so that each time it is clicked, the button will perform some type of animation. 我在这里有这个在线商店,显示项目,尺寸,价格等。我想在.add-to-cart-btn <button>添加一个动画,这样每次点击它时,按钮都会执行一些动画类型。 I could do this with jQuery something like: 我可以用jQuery做到这一点:

$(document).ready(function() {
  $('.add-to-cart-btn').on('click', function() {
    $(this).addClass('bounce').delay(1000).removeClass('bounce');
  });
});

but i'm trying to do things the "Angular Way" and I think i'm close. 但我正在尝试做“Angular Way”的事情,我想我很接近。 I have a directive here: thanks to This Post 我在这里有一个指示:感谢本帖

angular.module('ForeverLeather').directive('animateTrigger', ['$animate', function ($animate) {

  return function (scope, elem, attrs) {
    elem.on('click', function (elem) {
      scope.$apply(function() {
        var el = angular.element(document.getElementsByClassName("add-to-cart-btn"));
        var promise = $animate.addClass(el, "bounce");
        promise.then(function () {
          scope.$apply(function() {
            $animate.removeClass(el, "bounce");
          });
        });
      });
    });
  }
}]);

HTML HTML

  <div class="col-md-4 col-sm-6" ng-repeat="item in templateItems">

      <div class="product-img-wrapper">
        <img ng-src="{{item.src}}">
      </div>

      <h3 class="product-header">{{item.name}}</h3>
      <p class="lead product-text">
        {{item.description}}
      </p>

      <div class="product-btn-wrapper">
        <select ng-options="size.size as size.text for size in item.sizes" ng-model="item.selectedItem.size"
                class="form-control" ng-change="getPrice(item, item.selectedItem.size)">
          <option value="" disabled>-- Select to view prices --</option>
        </select>
        <span class="text-left product-price">{{item.selectedItem.price | currency}}</span>
        <button ng-click="addToCart(item.type, item.name, item.selectedItem.size);" 
                class="btn btn-lg btn-success add-to-cart-btn animated" animate-trigger>
          <i class="fa fa-cart-plus"></i>&nbsp; Add To Cart
        </button>
      </div>

    </div>

This works.. well kinda, my problem is that var el = angular.element(document.getElementsByClassName("add-to-cart-btn")); 这工作..好吧,我的问题是var el = angular.element(document.getElementsByClassName("add-to-cart-btn")); always find the first button on the page with this class name, I need to change this to something like: 总是找到带有这个类名的页面上的第一个按钮,我需要将其更改为:

var el = angular.element(elem); // invalid
var el = angular.element(this); // invalid

so that I am performing the animation on the currently clicked element instead of the first of the page. 这样我就可以在当前点击的元素而不是页面的第一个元素上执行动画。

But you already have the element, all you need is 但是你已经拥有了这个元素,你需要的就是它

return function (scope, elem, attrs) {
    elem.on('click', function () {
      scope.$apply(function() {
        var promise = $animate.addClass(elem, "bounce");
        promise.then(function () {
          scope.$apply(function() {
            $animate.removeClass(elem, "bounce");
          });
        });
      });
    });
  }

Animations in AngularJS are meant to be used another way. AngularJS中的动画意味着以另一种方式使用。

There are 4 types of animation events 有4种类型的动画事件

  • enter 输入
  • leave 离开
  • move 移动
  • add/remove class 添加/删除类

If you want to do it the 'Angular way' with javascript, then what you want to do is hook into these events. 如果你想用javascript做'Angular方式',那么你想要做的就是挂钩这些事件。

What you want to target in this case is the button like this: 在这种情况下你想要的目标是这样的按钮:

(From the docs: https://docs.angularjs.org/api/ngAnimate ) (来自文档: https//docs.angularjs.org/api/ngAnimate

myModule.animation('.slide', [function() {
  return {
    // make note that other events (like addClass/removeClass)
    // have different function input parameters
    enter: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);

      // remember to call doneFn so that angular
      // knows that the animation has concluded
    },

    move: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);
    },

    leave: function(element, doneFn) {
      jQuery(element).fadeOut(1000, doneFn);
    }
  }
}]

In order to hook into an event on-click, then enter , leave and move won't do you much good; 为了点击一个事件点击,然后enterleavemove对你没有多大好处; what you want is to add or remove a class name on the click event. 你想要的是在click事件上添加或删除一个类名。 You would could add the class in a number of ways, but here's one example: 您可以通过多种方式添加该类,但这是一个示例:

<button ng-class="{'my-animation':model.animationOn}" ng-click="model.animationOn=true">My Button Text</button>

You'd have to remove the class at some point, though. 但是,您必须在某个时候删除该课程。 The most appropriate time would probably be in the callback for that event using Angular's animation API. 最合适的时间可能是使用Angular的动画API在该事件的回调中。 Something like this: 像这样的东西:

myModule.animation('.my-btn', [function() {
  return {
    addClass: function(element, className, doneFn) {
      if(className == 'my-animation') {
        jQuery(element).fadeIn(1000, function() {
          doneFn(); // always call this when you're done
          element.removeClass('my-btn');
        });
      }
    }
  }
}]

Also , in order for Angular to know about you adding and removing classes in javascript, you have to use one of the directives that ship with Angular, or use the $animate service in angular. 另外 ,为了让Angular知道你在javascript中添加和删除类,你必须使用Angular附带的一个指令,或者在angular中使用$animate服务。 In your first code example, you are adding a class using jQuery, but Angular will not know about it. 在您的第一个代码示例中,您使用jQuery添加一个类,但Angular不会知道它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM