-
-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stimulus' controllers are not reconnecting after reflex, why? #314
Comments
You cannot combine Gem 3.2.3 and NPM 3.3.0-pre6. Versions have to match. |
This was the setup after following the Setup guide in the docs. I just changed the NPM version to match the Gem's and the behaviour is the same as above. |
Paul, you're an experienced developer. Come on, man. Don't blame the docs. You had to type those visibly different versions into the GH interface. I don't want to be mean but you have to admit this should have been your first flag. Anyhow, I see that you dropped your npm package down to 3.2.3 instead of bringing your gem version up to help test the major release that is coming in two days. Could you please upgrade your packages to the latest and greatest so that we're not troubleshooting code that won't matter in 36 hours? |
In the meantime, let me offer some tips on what I can see. First, you do not need to use Next, if you morph an element out of existance, and it is replaced by a new element that looks identical, it will be a new instance of the Stimulus controller. This is just how JS and the DOM interact. It would be like creating two identical objects in Ruby that both have different object_id's. The morphdom library which CableReady relies on attempts to do the least invasive DOM manipulations to get things changed to their new state. In theory, you should be able to change the innerHTML with a morph and it should just update the content, not replace the whole element. That said, there's unfortunately little we can do about it if morphdom wants to swap out. |
It was not to blame the docs but executing the following steps… $ rails new foo --webpack=stimulus --database=sqlite3 --skip-sprockets
$ cd foo
$ bundle add stimulus_reflex
$ bundle exec rails stimulus_reflex:install … i get this setup without defining any version: gem "stimulus_reflex", "~> 3.2" "stimulus_reflex": "^3.3.0-pre6", By the way, i think the docs are very well written and accessible.
Sure, my bad, i updated the Gem and NPM version to
The
I see (i hope). In this case an element is replaced by one that looks identical But i understand that this is more a "problem" of the interaction between morphdom and Stimulus. In a way it would be great if Stimulus controller elements could be brought to the state (eg. |
That seems so frustrating! I'm really sorry that you have to deal with that. It can be really hard to spot issues looking on a page, but if you end up putting your code on Github so that it's easy to clone and build locally, I'd be happy to take a look at whatever is bothering you. Unfortunately, I'm going to be pretty slammed until v3.3.0 finally releases on Tuesday. I feel like I'm organizing a wedding. |
Oh, a wedding, how nice! Thanks for looking into it, do not hurry, i can live with some Have a good evening (day?)! |
Hi Paul! I finally had a chance to clone your repo and go over everything carefully. I am now confident that I fully understand the nature of your inquiry and have a pretty good idea of what the outcome should be. My conjecture is that you've probably worked with React or other frameworks where components are expected to render themselves. Stimulus does not have a render concept because it's intended to imbue new behaviours into existing markup. In the context of SR, the expectation is that you would specify the UI you want to exist in the browser on the server. There's no need for a render stage because the markup is already perfect before it is sent down the wire. There is no build stage, no rehydration. We're not taking over the task of redrawing the UI from the browser. If you are working with a React component (or a Stimulus controller that renders markup during connect () {
this.element.addEventListener('stimulus-reflex:after', this.render)
}
disconnect () {
this.element.removeEventListener('stimulus-reflex:after', this.render)
} In summary: your best bet is to render the markup you desire. Failing that, you will need to tell your controllers to re-render after CableReady has its way with your DOM, because it sees the content your components rendered as differences from the DOM as the server thinks it should be. Note that this all goes away if you use selector morphs to target individual elements for update. |
Hi @leastbad and thanks a lot for your comprehensive answer, this is really helpful. I am not or have not been working with React but i understand the difference of approach about no need for a render stage because the markup is already perfect before it is sent down the wire; and this is also why i appreciate StimulusReflex so much. In case i need to keep or update states of elements using Stimulus, i'll use your solution using the Besides i hope the marriage went well and i am looking forward to give 3.3 a try. Thanks for your work and best, |
The issue is with with the stimilus tooltip controller, it add some element to the DOM which create issue when it's modified by StimulusReflex. See here for a more detailed explanation: stimulusreflex/stimulus_reflex#314 (comment)
The issue is with with the stimilus tooltip controller, it add some element to the DOM which create issue when it's modified by StimulusReflex. See here for a more detailed explanation: stimulusreflex/stimulus_reflex#314 (comment)
The issue is with with the stimilus tooltip controller, it add some element to the DOM which create issue when it's modified by StimulusReflex. See here for a more detailed explanation: stimulusreflex/stimulus_reflex#314 (comment)
Thanks again for working on StimulusReflex, i am starting to implement it in my Rails apps and it still is very (!) promising. In the following i encountered a problem using StimulusReflex which might exist on purpose, thus might not be a bug.
Problem
I have an element in the DOM hooked to a Stimulus controller
hello
which will be put in a specific state upon connection: its inner html will be set to "Hello, Stimulus!". After triggering a reflex on that same page, this element will again be morphed into the DOM but itsconnect()
function is not called and its inner html is lost.DOM before reflex:
DOM after "CounterReflex#increment" performed and morphed:
Though, if a new element using the
hello
controller is added to the DOM after a reflex, its controller is connected but the state of the previous ones will be lost.DOM after "CounterReflex#increment" performed and morphed (once):
DOM after "CounterReflex#increment" performed and morphed (twice):
To me it seems this behaviour is on purpose, but i wouldn't know why. It's quite common for me to bring elements into a certain state upon the connection of their controllers and this state always gets lost when they are "remorphed" into the DOM. We could make use of
data-reflex-permanent
in order to preserve them during morphs but this feels counter-intuitive to me.Could you tell me, why this behaviour exists and how to deal best with such situations? Obviously, it could be that i am missing out on something.
Thanks!
To Reproduce
Versions
StimulusReflex
External tools
Browser
The text was updated successfully, but these errors were encountered: