我首选的处理预销毁动画的方法是使用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() 方法来合并视图的隐藏和移除。
如果销毁实际上是在视图本身中开始的,您可以在调用destroy方法之前使用这些相同的原则,并使用.on('willDestroyElement')向控制器或路由发送一个动作,如果您需要在视图之后进行回调删除。
通过在didInsertElement 上运行this.$().hide,然后使用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 指定的任何值都是transitionDuration 的后备值,如果您想在覆盖默认JS transitionDuration 之前进行一些验证,您可以在上述方法中添加if ()。