Ember.js路由器:如何动画化状态转换

25

有人找到了一种好的方法来实现状态转换动画吗?

路由器会立即将视图从DOM中移除。这个问题在于我无法推迟它直到动画结束。注意:我正在使用 v1.0.0-pre.4


你是否考虑通过Ember.View#willDestroyElement将过渡类添加到你的视图中? - MilkyWayJoe
就此而言,我下面关于Ember Liquid Fire的回答被认为是今天处理这种情况的最佳实践 :) - max
6个回答

10
比利的计费刚刚发布了一个Ember 模块,支持动画过渡效果。

我刚开始接触Ember。 链接页面上说: “需要注意的事项:[...] 当使用不同的模型转换到相同路由时,动画不会执行。这是由于Ember重用相同的DOM元素的方式造成的,并且可能要等到1.1版中Ember核心支持动画才能解决。” 所以我的问题是 - 这个答案是否最新?在Ember 2.10中,动画路由的最佳选项是什么? - Benjamin

7

我知道这个问题很老了,但是今天处理特定上下文动画的最佳解决方案可能是 ember liquid fire

它可以让你在转换文件中做像这样的事情:

export default function(){
  this.transition(
    this.fromRoute('people.index'),
    this.toRoute('people.detail'),
    this.use('toLeft'),
    this.reverse('toRight')
  );
};

考虑到EmberJS在升级过程中确实经历了很多波动,因此对旧帖子的任何新信息都应该表示欢迎。因此,谢谢你! - Giacomo1968

7
我会扩展Lesyk的回答。如果您需要以DRY方式将其应用于多个视图,则可以创建一个自定义类,如下所示:
App.CrossfadeView = {
  didInsertElement: function(){
    //called on creation
    this.$().hide().fadeIn(400);
  },
  willDestroyElement: function(){
    //called on destruction
    this.$().slideDown(250);
  }
};

然后在你的代码中,你可以将它应用于各种视图类。由于Ember依赖于jQuery,因此你几乎可以使用任何jQuery动画。

App.IndexView = Ember.View.extend(App.CrossfadeView);
App.PostView = Ember.View.extend(App.CrossfadeView);

第一段代码的结尾有误,括号不匹配 :) 或许你可以编辑一下。 - graup
willDestroyElement动画在我的项目中无法正常工作(1.0-rc4)。似乎视图已经在动画渲染之前消失了。你有一个可用的例子吗? - graup
这是一个(未完成的)示例,使用了那个。动画效果不错:http://jsbin.com/imahog/21/edit 请注意,我正在使用 rc6,而且你关于方括号的正确(已在上面修复)。 - Bojan Markovic
1
谢谢。fadeIn 确实有效,但是 willDestroyElement 中的 slideDown 对我来说不可见。 - graup

6
在我的应用中遇到了同样的需求。尝试了Ember Animated Outlet,但它无法提供我所需要的细节度(元素特定动画)。
对我有用的解决方案是—— linkTo更改为action
{{#linkTo "todos"}}<button>Todos</button>{{/linkTo}}

成为...
<a href="#/todos" {{action "goToTodos"}}><button>Todos</button></a>

在当前控制器中创建goToTodos方法

App.IndexController = Ember.Controller.extend({
    goToTodos: function(){

        // Get Current 'this' (for lack of a better solution, as it's late)
            var holdThis = this;

        // Do Element Specific Animation Here
            $('#something').hide(500, function(){

                // Transition to New Template
                    holdThis.transitionToRoute('todos');

            });

    }
});

最后 -- 要在Todos模板中动画显示元素,请在视图上使用didInsertElement。
App.TodosView = Ember.View.extend({
    didInsertElement: function(){

        // Hide Everything
            this.$().hide();

        // Do Element Specific Animations Here
            $('#something_else').fadeIn(500);

    }
});

到目前为止,这是我发现的在过渡中针对特定元素进行动画的最优雅的解决方案。如果有更好的,非常愿意听取!


如果您正在为单个元素创建动画,则不涉及状态转换。ember-animated-OUTLET 用于出口,这与 OP 的用例有所不同。此外,操作会破坏应用程序的 URL 支持 :-( - mpowered

4
我找到了另一个可以在视图中实现动画效果的解决方案:ember-animate 示例:
App.ExampleView = Ember.View.extend({

    willAnimateIn : function () {
        this.$().css("opacity", 0);
    },

    animateIn : function (done) {
        this.$().fadeTo(500, 1, done);
    },

    animateOut : function (done) {
        this.$().fadeTo(500, 0, done);
    }
}

演示: 作者个人网站

1
App.SomeView = Ember.View.extend({
  didInsertElement: function(){
   //called on creation
   this.$().hide().fadeIn(400);
  },
  willDestroyElement: function(){
   //called on destruction
   this.$().slideDown(250)
  }
});

1
我确实了解这些钩子,但是它们都无法帮助我完成工作。问题在于didInsertElement和willDestroyElement特定于该视图。为了使过渡平稳,我需要知道另一个视图(路由器正在转换的视图)是否就绪,然后执行动画/过渡,最后销毁以前的视图。因此,换句话说,我正在寻找更多异步行为。 - david8401

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接