I’m currently using Turbolinks along with Stimulus, and I think it would be useful to have a new lifecycle method that gets called once and is not called again for Turbolinks visit
s. This is helpful for “higher-order controller” that manage state for the entire browsing session. This is simply an optimization, because without Turbolinks, everything will be reloaded again on every page load anyways.
Does the initialize callback not handle this? Is it being called on Turbolinks visits?
Am I reading this wrong? https://stimulusjs.org/handbook/managing-state#lifecycle-callbacks-explained
From what I’m seeing on my console logging, it goes through the entire lifecycle for every turbolinks visit:
initialize => connect => disconnect
Also, interestingly, when you navigate back and turbolinks loads from cache and then replaces the cache with the freshly fetched page, you’ll see:
initialize => connect => disconnect => initialize => connect => disconnect
I have exact the same problem - if i’m getting this well, initialize should be called just once but it gets called for each visit.
So, when i have a controller on /foo
and i call Turbolinks.visit('/foo')
, initialize()
of this controller gets called twice - once for page load and second for Turbolinks.visit
Ok if anyone needs that: to make it call initialize just once, you need to:
- add
data-turbolinks-permanent
attribute to the element - set an unique
id
attribute for that element
I’m using Stimulus as a wrapper around datatables. For me, adding data-turbolinks-permanent
did not solve the problem.
Instead, I check whether we’re dealing with the preview and don’t attempt to mount the plugin if so:
if (!document.documentElement.hasAttribute("data-turbolinks-preview")) {
this.datatableMount()
document.addEventListener("turbolinks:before-cache", () => this.datatableUnmount(), { once: true })
}