Ember 过渡和渲染完成事件

IT技术 javascript ember.js promise transitions
2021-03-02 10:59:09

是否触发了任何事件,说明转换/渲染已完成(并且 dom 可见/准备就绪)。

setupcontroller/activate 是在构建/渲染 dom 之前

didInsertElement 只有在我已经插入一个元素并且我只是将模型切换到它下面的第一次时才会被触发。

我真正在寻找的是过渡完成事件

我想我可以做到这一点,但我有点希望它已经内置了......

Ember.Router.reopen({
  didTransition:function(infos) {
     this._super(infos);
     console.log('transition complete');  
  }
});

更酷的是对转换完成的路由的回调,我可能不得不写这个并提交拉取请求。

4个回答

有几种不同的方法可以解决这个问题

插入元素

这在第一次插入视图时被触发,但如果模型在视图下被切换出则不会被触发(因为 Ember 喜欢重用项目,因为它比重建整个 DOM 便宜)。下面举例。

简单的

如果你只需要做一次,第一次插入视图时,使用 didInsertElement

App.FooView = Em.View.extend({
  setupSomething: function(){
    console.log('the dom is in place, manipulate');
  }.on('didInsertElement')
});

示例:http : //emberjs.jsbin.com/wuxemo/1/edit

复杂的

如果您需要在从路由本身渲染 DOM 之后安排某些事情,您可以使用schedule它并将其插入afterRender队列中。

App.FooRoute = Em.Route.extend({
  setupController: function(controller, model){
    this._super('controller', model);
    Ember.run.schedule('afterRender', this, function () {
      //Do it here
    });
  }
});

示例:http : //emberjs.jsbin.com/wuxemo/2/edit

过渡Promise

过渡的Promise将在完成渲染项目之前完成。但是当它完成获取所有模型和控制器并将它们连接起来时,它为您提供了一个钩子。

如果你想连接到 transition 事件,你可以这样做:

var self = this;
transitionTo('foo').then(function(){
    Ember.run.schedule('afterRender', self, function () {
          //Do it here
    });
})
仅供参考:scheduleOnce匿名函数传递给它不会“一次”调度它,因为它正在检查函数引用以查看它是否已经被调度。您需要在静态的某个地方(例如在对象上)定义函数,因此它是:Ember.run.scheduleOnce('afterRender', this, this.myStaticFunction)
2021-05-01 10:59:09
是的,很棒的一点,在我写这篇文章的时候,我没有意识到这一点,并且在我的答案中没有做足够的清理。很棒的一点,并进行了更新,以免给人错误的印象。去抖和节流也是如此(并且经常被误解)
2021-05-06 10:59:09
组件可以监听renderComplete事件吗?
2021-05-12 10:59:09

afterModel挂钩可能会为你工作:

App.MyRoute = Ember.Route.extend({
  afterModel: function(model, transition) {
    transition.then(function() {
      // Done transitioning
    });
  }
});

我使用 RC-7 和具有和不具有动态段的路由(即,具有模型的路由和没有模型的路由)对此进行了测试。它似乎以任何一种方式工作。

有关 RC-6 示例,请参阅此 JSBin:
  输出:http : //jsbin.com/OteC/1/
  来源:http : //jsbin.com/OteC/1/edit?html, js

这个Promise解析对于知道转换已经完成是非常好的。非常适合在视图中调用控制器属性并知道您拥有正确的模型。
2021-04-25 10:59:09
据我所知,在最新的 Ember 中不起作用。如果在 afterModel() 中,您尝试访问路由器模板中不存在的 DOM 元素
2021-04-28 10:59:09
我现在就可以吻你。我的 afterModel 正在对父控制器进行模型更改,但模板没有更新新数据。我将更改移至 transition.then,一切都好起来了。
2021-05-17 10:59:09
谢谢,正是我需要的。在 Ember 1.7.0 中运行良好。
2021-05-18 10:59:09

setupController是路由器在完成转换之前调用的最后一件事。如果它没有错误地完成,就 Ember 而言,过渡就完成了。您实际上可以通过启用LOG_TRANSITIONS_INTERNAL.

此时,控制器是否抛出错误、视图是否抛出错误等都没有关系。路由器已完成过渡到目标路由。

因此,setupController在对应于路由器方面的最后的地方didTransition

当支持控制器的内容/模型在现有视图上发生更改时,绑定就会启动。此时发生在视图上的大多数更改都是通过 Metamorphing 进行的。

我能想到的最接近的地方是View.render将更改推送到RenderBuffer. 但是您仍然需要通过此处发生的混合来解释 Metamorphing。

为了迂腐,我会说“setupController是路由器在完成转换后调用的第一件事”,尽管我认为这取决于您分配给“完成”一词的精确语义。
2021-04-27 10:59:09

didTransition 确实如你所愿存在——但它是一个动作而不是一个钩子

XXRouter
actions: {
    didTransition: function() {
        this.controller.set("hasTransitioned", true); // or whatever is needed?!
        return true; // Bubble the didTransition event
    },
}


XXController    
observeTransition: function() {
    alert('complete Transition');
}.observes('hasTransitioned'),