6

現在、Ember でビューの破棄を遅らせる方法はありません。これは、ビューを破棄する前にビューをアニメーション化する場合に問題を引き起こします。

だから、私は現在、この非常に醜い回避策を持っています:

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

注: アニメーションは.animate-destructioncss のクラスで行われます。

私の方法が悪いことはわかっているので、誰かがより良い方法を思いついたのではないかと思っています。

4

3 に答える 3

1

これは私の側からの自発的なアイデアです。

これは、Ember.View での destroyElement の実装です (ソースへのリンク)。

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

このメソッドをオーバーライドして、アニメーションを実行できます。

destroyElement: function() {
    var completeCallback = function(){
        return this.currentState.destroyElement(this);
    }
    this.$().fadeOut(completeCallback); //or whatever animation
},
于 2013-02-26T15:31:33.533 に答える
1

これを試して

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);
    });
},
});
于 2014-06-29T11:45:53.253 に答える
0

破壊前のアニメーションを処理するための私の推奨方法は、 を使用することEm.Eventedです。ビューの破棄を開始するメソッドまたはアクションで呼び出されるイベントをビューにリッスンさせ、イベントによってトリガーされたメソッドが完了するまで破棄を遅らせます (実行ループを使用)。例えば:

SomeView = Em.View.extend({

  _listen: function() {
    this.get('controller').on('closeChildView', this, this.hide);
  }.on('willInsertElement'),

  hide: function() {
    this.$().fadeOut(this.get('controller.duration'));
  }

});

そして、コントローラーで:

Em.ObjectController.extend(
  Em.Evented, { // Important mixin!

  duration: 500,

  actions: {
    removeSomeChildView: function() {
      this.trigger('closeChildView');

      Em.run.later(this, function() {
        // Then do the stuff to destroy the view here.
      }, this.get('duration'));
    }
  }

});

または、ビューでメソッドを使用してthis.removeFromParent()、ビューの非表示と削除を統合することもできます。

破棄がビュー自体で実際に開始された場合は、破棄メソッドを呼び出す前にこれらの同じ原則を使用.on('willDestroyElement')し、ビューが削除された後にコールバックが必要な場合にコントローラーまたはルートにアクションを送信するために使用できます。

破棄前のアニメーションは、ビュー要素を遷移するメソッドを実行this.$().hidedidInsertElementてから使用することで、同じ方法で実行できます。show()

JS と CSS の遷移時間の調整

すべてのトランジションの一部を CSS で行う場合、CSS と JS の間のトランジション時間が一致していることを確認する必要があります。これはとても簡単です。ビューで、CSS トランジションがビューの要素で行われることを確認してから、次のようにします。

SomeView = Em.View.extend({
  transitionDuration: Em.computed.alias('controller.transitionDuration'),

  setTransitionDuration: function() {
    var ms = parseFloat(this.$().css('transition-duration')) * 1000; // In milliseconds

    if (ms) {
      this.set('transitionTime', ms);
    }
  }.on('didInsertElement'),
});

これにより、ビューとコントローラーの遷移時間が更新され、CSS に記述したものと一致します。コントローラーで指定しtransitionDurationた値はフォールバック値であり、デフォルトの JS をオーバーライドする前に検証を行う必要がある場合は、上記のメソッドに をtransitionDuration追加できます。if ()transitionDuration

于 2015-01-09T14:57:55.460 に答える