Search code examples
javascriptjquerybackbone.jsmarionetteeventtrigger

What is the proper view lifecycle of a Marionette View?


I am currently using Marionette 2.4.1.

I have a parent layout view (A) that contains a region that a child layout view (B) will show onto. I have a onShow method on view (B) which is properly called when view (B) is shown. However, I have a onEmpty and onBeforeEmpty on view (B) to expect them to be called when view (B) is hidden. These are called from view (A) where I have a function that will empty out the region that view (B) populates however I pass {preventDestroy: true} on the empty call.

My issue is, I was/am expecting view (B) to pick up on that before:empty or empty triggers that are called when #empty is called from view (A) however, view (B) does not pick up those triggers. Not even view (B) seems to pick up on those triggers either.

What is the expected situation here? When running through the Marionette source code, I can see the onBeforeEmpty trigger being called as per my source code:

Marionette._triggerMethod = (function() {
    // split the event name on the ":"
    var splitter = /(^|:)(\w)/gi;

    // take the event section ("section1:section2:section3")
    // and turn it in to uppercase name
    function getEventName(match, prefix, eventName) {
      return eventName.toUpperCase();
    }

    return function(context, event, args) {
      var noEventArg = arguments.length < 3;
      if (noEventArg) {
        args = event;
        event = args[0];
      }

      // get the method name from the event name
      var methodName = 'on' + event.replace(splitter, getEventName);
      var method = context[methodName];
      var result;

      // call the onMethodName if it exists
      if (_.isFunction(method)) {
        // pass all args, except the event name
        result = method.apply(context, noEventArg ? _.rest(args) : args);
      }

      // trigger the event, if a trigger method exists
      if (_.isFunction(context.trigger)) {
        if (noEventArg + args.length > 1) {
          context.trigger.apply(context, noEventArg ? args : [event].concat(_.drop(args, 0)));
        } else {
          context.trigger(event);
        }
      }

      return result;
    };
  })();

Here is where I suspect it to trigger the method onBeforeEmpty:

// get the method name from the event name
      var methodName = 'on' + event.replace(splitter, getEventName);
      var method = context[methodName];

It seems like the context is view (A).

Mariontte's Region#Empty:

// Destroy the current view, if there is one. If there is no
    // current view, it does nothing and returns immediately.
    empty: function(options) {
      var view = this.currentView;

      var preventDestroy = Marionette._getValue(options, 'preventDestroy', this);
      // If there is no view in the region
      // we should not remove anything
      if (!view) { return; }

      view.off('destroy', this.empty, this);
      this.triggerMethod('before:empty', view);
      if (!preventDestroy) {
        this._destroyView();
      }
      this.triggerMethod('empty', view);

      // Remove region pointer to the currentView
      delete this.currentView;

      if (preventDestroy) {
        this.$el.contents().detach();
      }

      return this;
    },

So here this.triggerMethod('before:empty', view); it seems like this refers to view (A) and view refers to view (B). Is this intended? I thought the method would be triggered on view (B)? However, I cannot seem to see the method being triggered on view (A) either.


Solution

  • This this in this.triggerMethod('before:empty', view); refers to your the region of your layout. You can see more region lifecycle events/methods here: http://marionettejs.com/docs/v2.4.3/marionette.region.html#events-raised-on-the-region-during-show

    If you are looking for methods to use in your view, onDestroy and onBeforeDestroy are probably what you are looking for. Views are 'destroyed' and Regions are 'emptied'. http://marionettejs.com/docs/v2.4.3/marionette.view.html#view-onbeforedestroy