Which lifecycle hooks to use?

I’m using a tabbed app layout within a app root component. The app root component toggles between a login view, and tabbed views based on login status. This all works great.

One of my tabs has a event listener. I expected the pageBeforeRemove event or Destroy lifecycle hook to be called whenever the root app component toggles between both states, so I can unregister the event listener. But this doesn’t happen, so if you logout/login a new event handler is added and event is handled twice.

I think it is because the initialized view components stays in memory because the app root component is updated through VDOM. Is there a way to ‘detect’ if a view is removed from DOM, so I can unregister the event handlers? Or should I do that another way on logout?

    ...
    on: {
	  pageInit: function(e, page) {
	    this.$app.on('myEvent', this.do_refresh);
	  },
      // never called:
	  pageBeforeRemove: function(e, page) {
	    this.$app.off('myEvent', this.do_refresh);
	  },
    },
    // also never called:
    destroyed: function(e) {
      this.$app.off('myEvent', this.do_refresh);
    }
    ...

My app root component structure is like this:

<div id="app">
  {{#if logged_in}}

	<div id="view-container" class="views tabs safe-areas">
	    <!-- Tabbar for switching views-tabs -->
	    <div class="toolbar tabbar tabbar-labels toolbar-bottom">
		  <div class="toolbar-inner">

		    <a href="#view-a" class="tab-link tab-link-active">
			  <i class="icon f7-icons">square_grid_2x2_fill</i>
			  <span class="tabbar-label">Home</span>
		    </a>

		    <a href="#view-b" class="tab-link" data-force-refresh="true">
			  <i class="icon material-icons">people</i>
			  <span class="tabbar-label">Tab 2</span>
		    </a>

		    <a href="#view-c" class="tab-link" data-force-refresh="true">
			  <i class="icon material-icons">more_horiz</i>
			  <span class="tabbar-label">Tab 3</span>
		    </a>

		  </div>
	    </div>

	    <div id="view-a" class="view view-init tab tab-active" data-url="/homepage"</div>
	    <div id="view-b" class="view view-init tab" data-url="/tab-2"></div>
	    <div id="view-c" class="view view-init tab" data-url="/tab-3"></div>

	</div>

  {{else}}

	<div
		id="view-login"
		data-url="/login-type"
		class="view view-init view-main"
		data-name="view-login"
	></div>

  {{/if}}
</div>

The View instance should be destroyed in this case, so you might want to listen for that event:

this.$el.parents('.view').on('before:destroy', () => { ... })
1 Like

Ah, great, I’ll try this next week. I figured as well that I could also emit a “logout” event, to allow components to unregister their events. Maybe it’s an idea to add a method to $app to unregister all event handlers, but I don’t know if this is as easy as it looks like.

Currently, I show the splashscreen and reload the app at logout. This doesn’t take longer than 1 second, so no obvious delay.

1 Like