marionette.js view difference between onShow vs onRender?
Asked Answered
M

4

18

I am new to Marionette.js and while I am refactoring my existing Backbone.js code, I noticed there are two callbacks on Marionette view (itemview) that looked to me similar, i.e. onRender and onShow. What is the difference and better way of using them ?

However, looking at source code, i think both "render" and "show" events are raised inside "view initialize".

constructor: function(){
    _.bindAll(this, "render");

    var args = Array.prototype.slice.apply(arguments);
    Backbone.View.prototype.constructor.apply(this, args);

    Marionette.MonitorDOMRefresh(this);
    this.listenTo(this, "show", this.onShowCalled, this);
}
Metabolite answered 14/6, 2013 at 17:47 Comment(0)
M
20

onShow : view itself doesn't trigger 'show' event. It triggers by a region. So it will not be called in some cases.

onRender : this method executes every time the view is rendered.

Mousterian answered 14/6, 2013 at 18:31 Comment(3)
However, looking at source code, i think both "render" and "show" events are raised inside "view initialize" .... ` constructor: function(){ _.bindAll(this, "render"); var args = Array.prototype.slice.apply(arguments); Backbone.View.prototype.constructor.apply(this, args); Marionette.MonitorDOMRefresh(this); this.listenTo(this, "show", this.onShowCalled, this); }`Metabolite
No, ItemView (extends from View) just subscribes to the show event - this.listenTo(this, "show", this.onShowCalled, this); and doesn't trigger it. render event triggers inside the render method, not on the view initialize. So it can be called at any time manually.Mousterian
Also, I don't think onRender is available on plain views -- only on itemviews.Cote
O
42

I think there is something not totally correct in Vitaliy's answer. The correct will be:

onShow : view itself doesn't trigger 'show' event. It triggers by a region. So it will not be called in some cases.

onRender : this method executes every time the view is rendered.

Note that 'onRender' being executed doesn't mean that the object is actually added to the DOM. It just means that it was just rendered (data filled the template, you have a this.$el to deal with, etc.)

On the other hand, if 'onShow' is called because the 'show' event has been triggered from a region, and as regions usually represent an element within the DOM, you might expect that when 'onShow' is called, the view is indeed added to the DOM.

Obsessive answered 2/12, 2013 at 17:55 Comment(5)
This is correct, the statement that onRender fires after an element has been inserted into the DOM is misleading and will confuse a lot of people.Moorer
Why not just improve the answer?Mousterian
Sorry, I didn't know I could do that :/ I just edit the answer and change it, or I need to do something more? Again, my apologies :(Obsessive
For accessibility purposes, there are cases where you'll need to put focus on elements as soon as they are added to the DOM so screen readers can read their content. For example, when a loading spinner appears it may have text in its view, so you can use a bit of jQuery: this.$('#spinner-title').focus();. But I noticed the focus only actually takes place on onShow , not on onRender. This shows the difference between the two types of callbacks.Bramble
There is one more available event, onDomRefresh, which gets called when the view is moved from the "shadow DOM", where all off-screen rendering happens for performance reasons, to the real DOM.Cornejo
M
20

onShow : view itself doesn't trigger 'show' event. It triggers by a region. So it will not be called in some cases.

onRender : this method executes every time the view is rendered.

Mousterian answered 14/6, 2013 at 18:31 Comment(3)
However, looking at source code, i think both "render" and "show" events are raised inside "view initialize" .... ` constructor: function(){ _.bindAll(this, "render"); var args = Array.prototype.slice.apply(arguments); Backbone.View.prototype.constructor.apply(this, args); Marionette.MonitorDOMRefresh(this); this.listenTo(this, "show", this.onShowCalled, this); }`Metabolite
No, ItemView (extends from View) just subscribes to the show event - this.listenTo(this, "show", this.onShowCalled, this); and doesn't trigger it. render event triggers inside the render method, not on the view initialize. So it can be called at any time manually.Mousterian
Also, I don't think onRender is available on plain views -- only on itemviews.Cote
M
7

Well, this is the show method in Marionette and it explains the question

show: function(view){

       this.ensureEl();

       var isViewClosed = view.isClosed || _.isUndefined(view.$el);

       var isDifferentView = view !== this.currentView;

       if (isDifferentView) {
         this.close();
       }

       view.render();

       if (isDifferentView || isViewClosed) {
         this.open(view);
       }

       this.currentView = view;

       Marionette.triggerMethod.call(this, "show", view);
       Marionette.triggerMethod.call(view, "show");
     }
Metabolite answered 18/6, 2013 at 16:48 Comment(0)
N
0

In version 3 the region events show and before:show are no longer triggered on the view. You can use render and before:render events in most cases. If you need to know that the view is in the DOM then you can use attach or dom:refresh

info http://blog.marionettejs.com/2016/08/23/marionette-v3/index.html

Nimble answered 15/11, 2016 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.