Open meceo opened 11 months ago
Thank you for opening this issue.
From a Stimulus perspective, Controllers shouldn't be doing any property caching or memoization of their targets. Every time a this.[name]Target
or this.[name]Targets
property is accessed, the controller should query its scope to find the appropriate elements. Neither morphing nor full-page reloading shouldn't be affecting that logic, since it's a fetch each time.
With that in mind, I wonder what's preventing changes to the target's attributes during the morph. Could you share some more details about your project, particularly the changes you've layer on top of what's provided by https://github.com/stimulus-components/stimulus-rails-nested-form?
hi Sean,
I fully agree that the controllers shouldn't be doing any property caching or memoization of the targets. Please have a look at the minimalistic rails app that reproduces the issue: https://github.com/meceo/morph_testing
Please notice that commenting out line <%= turbo_refreshes_with method: :morph, scroll: :preserve %>
in layout.html.erb brings the proper behaviour back - the newest random value from the server is used.
The document
itself seems to have other values such as authenticity_token properly updated, but not tags inside the \<template> tag. No wonder why querying within document doesn't return expected values:
Perhaps changes detection algorithm in morph doesn't work well with #document-fragment elements?
isn't it related to this issue https://github.com/bigskysoftware/idiomorph/issues/15 ?
looks like Idiomorph won't update <template>
elements
@meceo Thank you for clarifying, and thank you @adrienpoly for linking to https://github.com/bigskysoftware/idiomorph/issues/15.
I think Turbo could incorporate explicit <template>
element support as part of its call to Idiomorph.morph
.
FWIW, I'm working on an optimistic UI implementation using <template>
containing turbo stream actions that are rendered inline. Currently this fails for the same reason, <template>
tags not being merged by Idiomorph. It's certainly a bit of an edge case, but could be powerful, if <template>
tags were reconciled with the rest of the DOM.
@meceo Thank you for clarifying, and thank you @adrienpoly for linking to bigskysoftware/idiomorph#15.
I think Turbo could incorporate explicit
<template>
element support as part of its call toIdiomorph.morph
.
You can implement a callback similar to the one suggested here by connecting to the turbo:morph event.
But I think it would be nice if Turbo handled this automatically, since it's a big gotcha otherwise. wdyt @jorgemanrubia ?
I've opened https://github.com/bigskysoftware/idiomorph/pull/49 to try and resolve this issue in the upstream dependency.
In the meantime, like @ghiculescu suggests something like this snippet might suffice as a backwards-compatible workaround (replacing the turbo:morph
event suggested above with turbo:morph-element):
addEventListener("turbo:morph-element", ({ target, detail: { newElement } }) => {
if (target instanceof HTMLTemplateElement && newElement instanceof HTMLTemplateElement) {
target.innerHTML = newElement.innerHTML
}
})
https://github.com/bigskysoftware/idiomorph/pull/49 has been merged upstream into Idiomorph, and is likely to be part of the next release.
You’re the man @seanpdoyle 👊
I test page refreshes on a small project. the project uses https://github.com/stimulus-components/stimulus-rails-nested-form
I have \<template> tag that has some attributes preset. The presets change according to user actions that triggers new page content from server response. After activating morph I noticed the attribute that is used to add nested element is always the old one (tested by simply adding
console.log(this.templateTarget.innerHTML)
in this line) even though the server returns new one with proper values. After full refresh the presets are correct (new ones). Before morph activation the page would reload as normal turbo (body replace) and \<template> would have correct values when adding using nested form feature.