Meteor Animation

I am trying to implement an animation where an item animates to the left after it gets selected. The following code works. But only about 80% of the time.

JS

//myItem
Template.myItem.rendered = function(){
  if(Session.get("selected_item") === this.data._id){
    $(this.firstNode).addClass("selected");
  } else {
    $(this.firstNode).removeClass("selected");
  }
};

Template.myItem.events({
  "click .myItem": function(evt, template){
    Session.set("selected_item", this._id);
  }
});


//myItemList
Template.myItemList.helpers({
  items: function(){
    return Items.find();
  }
});

Templates

<template name="myItem">
  <div class="myItem">{{name}}</div>
</template>

<template name="myItemList">
  {{#each items}}
    {{> myItem}}
  {{/each}}
</template>

CSS

.myItem { transition: all 200ms 0ms ease-in; }
.selected { left: -20px; }

I also tried to wrap the code into a Meteor.defer() to make sure that really everything is ready to do the animation.

Template.myItem.rendered = function(){
  Meteor.defer(function() {
    if(Session.get("selected_item") === this.data._id){
      $(this.firstNode).addClass("selected");
    } else {
      $(this.firstNode).removeClass("selected");
    }
  });
};

But that results in this kind of error:

Exception from defer callback: TypeError {}

It would be great to see any ideas how to make the animation work every time.

UPDATE

Krab got the right answer. The exception was coming from the this reference. I want to add some details. So here are two working versions on how to do the animation:

with Meteor.defer()

Template.myItem.rendered = function(){
  var instance = this;
  if(Session.get("selected_item") === this.data._id){
    Meteor.defer(function() {  
      $(instance.firstNode).addClass("selected"); //use "instance" instead of "this"
    });
  }
};

(We don't actually need the else block here because meteor will remove the selected class if it redraws the item.)

or with $().animate()

Template.myItem.rendered = function(){
  if(Session.get("selected_item") === this.data._id){
    $(this.firstNode).animate({
      left: "-20px"
    }, 300);
  }
};

If you use the jQuery approach you need to remove the CSS code.

.myItem { transition: all 200ms 0ms ease-in; }
.selected { left: -20px; }


试试这个,因为this指针在延迟回调方面与代码直接在渲染回调中执行是不一样的

Template.myItem.rendered = function(){
  var self = this;
  Meteor.defer(function() {
    if(Session.get("selected_item") === self.data._id){
      $(self.firstNode).addClass("selected");
    } else {
      $(self.firstNode).removeClass("selected");
    }
  });
};
链接地址: http://www.djcxy.com/p/14756.html

上一篇: 选择输入中的所有文本,focusin

下一篇: 流星动画