Переход Ember и событие завершения рендеринга

Есть ли какое-либо событие, указывающее, что переход/рендеринг завершен (и дом виден/готов).

setupcontroller/activate перед построением/рендерингом dom

didInsertElement запускается только в первый раз, когда я уже вставил элемент и просто переключаю модель под ним.

То, что я действительно ищу, это событие перехода завершено

Думаю, я могу это сделать, но я надеялся, что это уже встроено...

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

Еще круче был бы обратный вызов маршрута, который завершил переход для него, возможно, мне придется написать это и отправить запрос на включение.


person Kingpin2k    schedule 02.07.2013    source источник
comment
взгляните на этот gist gist.github.com/machty/5723945 описанные там изменения уже в RC6   -  person intuitivepixel    schedule 03.07.2013
comment
Да, я это видел. Это частично помогло, единственная проблема заключалась в том, что я мог запускать код после перехода, но это все еще не после того, как он был вставлен в дом.   -  person Kingpin2k    schedule 12.07.2013


Ответы (4)


Есть несколько способов решить эту проблему

сделалInsertElement

Это запускается, когда представление вставляется в первый раз, но не запускается, если модель переключается под представлением (потому что 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

Обещание перехода

Промис перехода завершится до завершения рендеринга элементов. Но это дает вам подсказку, когда все модели и контроллеры будут извлечены, а затем подключены к ним.

Если вы хотите подключиться к событию перехода, вы можете сделать это так:

var self = this;
transitionTo('foo').then(function(){
    Ember.run.schedule('afterRender', self, function () {
          //Do it here
    });
})
person Kingpin2k    schedule 22.08.2013
comment
К вашему сведению: передача анонимных функций в scheduleOnce не запланирует их один раз, так как они проверяют ссылку на функцию, чтобы увидеть, не запланирована ли она уже. Вам нужно будет определить функцию где-то статично (например, на объекте), так что это: Ember.run.scheduleOnce('afterRender', this, this.myStaticFunction) - person Ben Lesh; 11.08.2014
comment
Да, отличный момент, когда я писал, что не знал об этом и недостаточно подчистил свои ответы. Отличное замечание, и обновлено, чтобы не создавать неправильного впечатления. Это верно и для подавления дребезга и газа (и часто неправильно понимается). - person Kingpin2k; 12.08.2014
comment
могут ли компоненты прослушивать события renderComplete? - person SuperUberDuper; 16.03.2015

Вам может подойти хук afterModel:

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

Я протестировал это с помощью RC-7 с маршрутами, которые имеют и не имеют динамических сегментов (т. е. маршрут с моделью и маршрут без модели). Кажется, это работает в любом случае.

См. этот JSBin для примера RC-6:
Вывод: http://jsbin.com/OteC/1/
Источник: http://jsbin.com/OteC/1/edit?html,js

person Rocky    schedule 21.08.2013
comment
Это решение-обещание лучше всего подходит для понимания того, что переход завершен. Идеально подходит для вызова свойств контроллера в представлениях и определения правильной модели. - person Matthew Blancarte; 23.11.2013
comment
Спасибо, именно то, что мне было нужно. Отлично работает в Ember 1.7.0. - person rog; 16.10.2014
comment
Я мог бы поцеловать тебя прямо сейчас. Моя модель afterModel вносила изменения в модель родительского контроллера, но шаблон не обновлял новые данные. Перенес изменение в переход.тогда и все стало лучше. - person colsen; 02.10.2015
comment
Насколько я вижу, не работает в последней версии Ember. Если в afterModel() вы пытаетесь получить доступ к элементу DOM, который находится в шаблоне маршрутизатора, он не существует. - person Epirocks; 04.08.2016

setupController — это последнее, что вызывает маршрутизатор перед завершением перехода. И если он завершится без ошибок, с точки зрения Ember переход завершен. Вы действительно увидите это в действии, включив LOG_TRANSITIONS_INTERNAL.

В этот момент не имеет значения, выдал ли контроллер ошибку, представление выдало ошибку и т. д. Маршрутизатор завершил переход на целевой маршрут.

Таким образом, setupController — это последнее место с точки зрения маршрутизатора, которое соответствует didTransition.

Когда содержимое/модель, поддерживающая контроллер, изменяется в существующем представлении, вступают в силу привязки. Большинство изменений, которые происходят с представлением в этот момент, происходят посредством метаморфинга.

Ближайшее место, которое я могу придумать, это View.render, которое подталкивает изменения в RenderBuffer. Но вам все еще нужно учитывать метаморфозы через примеси, которые происходят здесь.

person Darshan Sawardekar    schedule 03.07.2013
comment
Чтобы быть педантичным, я бы сказал, что setupController — это первое, что маршрутизатор вызывает после завершения перехода, хотя я полагаю, что это зависит от точной семантики, которую вы присваиваете слову finalize. - person ; 05.06.2015

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'),
person Gabe Rainbow    schedule 07.04.2015