Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animating views before destruction in Emberjs

Tags:

ember.js

There is currently no way to delay view destruction in Ember. This presents a problem when you want to animate the view before destroying it.

So, I currently have this extremely ugly workaround:

willDestroyElement: ->
  $clone = @$().clone().addClass "animate-destruction"
  @$().parents(':first').prepend $clone
  setTimeout ->
    $clone.off().remove()
  , 350

Note: animation is done in the .animate-destruction class in css.

I know my method is bad, so I'm wondering if anyone has come up with a better way.

like image 930
Teddy Zeenny Avatar asked Feb 26 '13 15:02

Teddy Zeenny


2 Answers

This is just an spontaneous idea from my side:

This is the implementation of destroyElement in Ember.View (Link to Source):

 destroyElement: function() {
    return this.currentState.destroyElement(this);
  },

You could try to override this method to do your animation:

destroyElement: function() {
    var completeCallback = function(){
        return this.currentState.destroyElement(this);
    }
    this.$().fadeOut(completeCallback); //or whatever animation
},
like image 146
mavilein Avatar answered Sep 19 '22 10:09

mavilein


Try this

Ember.Route.extend({
actions: {
willTransition: function(transition) {
        $.each(Ember.View.views, function(index, value) {
            var popUpView = value.get('classNames').find(function(item) {
                return item == '[nameofyourclass]';
            });
            if(!Em.isEmpty(popUpView) && value.get('visible')) {
                value.set('visible', false);
                value.get('controller').set('previousTransition', transition);
                transition.abort();
            }
        });
        return true;
},
 }
    });

Ember.View.extend({
classNames: ['nameofyourclass'],
classNameBindings: ['visible:element-visible'],

visible: false,

didInsertElement: function() {
    var t = this,
            controller = this.get('controller');
    this.$()
    .on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {
        if(!t.get('visible')) {
            var previousTransition = controller.get('previousTransition');
            if(!Em.isEmpty(previousTransition)) {
                controller.set('previousTransition', null);
                previousTransition.retry();
            } else { // fallback
                controller.transitionToRoute('index');
            }
        }
    });
    Em.run.next(this, function() {
        this.set('visible', true);
    });
},
});
like image 38
Everydaypanos Avatar answered Sep 18 '22 10:09

Everydaypanos