Comments (4)
The way v2 is set up, we instruct devs to call initialize in their index.js. This is great from a magic perspective but it means we quietly lose some flexibility. For example, it might be nice to override StimulusReflexController with a custom controller. The reason is that this "stimulus-reflex" controller is the ideal place to put callback functions.
I got pretty stuck on this today because for the life of me, I couldn't figure out a reliable way to structure a callback.
I had to stare into space for a while before the lightbulb came on: I'm so used to async calls that I completely forgot websockets is a stateful channel and there is no callback in the standard JS scoped function sense.
This realization was good because now I can actually propose a potentially workable solution that I think works well and I don't think it has to break the API - although we might want to, given the above points about overriding the StimulusReflexController.
Note: I'm about to propose a small addition to cable_ready.
In stimulus_reflex/lib/channel.rb#broadcast_morph line 97 we tell cable_ready to send the updated html body to the client. When I look at the source for cable_ready, I see that it adds a cable_ready: true pair to the payload.
What I propose is that you add an additional parameter to cable_ready::channel#morph (and possibly the other "operations" responses) that accepts a hash of application specific metadata that would be delivered with the payload alongside cable_ready: true.
We can use this hash to pass the @target from the reflex, allowing code inside the receive method to access an object called data.metadata.
Then in stimulus_reflex.js, on line 26 after we call CableReady.perform(data.operations) we can access data.metadata['target'] and parse out the controller and reflex action that triggered the transaction.
Stimulus could then test the appropriate controller for the existence of a callback method, and if it exists, execute it. Note that this method would not receive an element, so it would be responsible for all querySelector operations it needs to do.
So, imagine that I have clicked a todo item and initiated an edit reflex. A textbox is now in the DOM and we want it to receive focus. After the DOM is replaced, stimulus_reflex checked the Todos controller for a method called editCallback. Finding it, it executes it. That method contains document.querySelector('[autofocus]').focus()
and since I've modified my index.html.erb template to suppress the autofocus attribute on the new-todo textbox when its in edit mode, it picks up the only element in the DOM with the autofocus attribute set, which is our new textbox. It receives keyboard focus. There are fireworks.
I like the idea of attaching the target to the cable_ready payload regardless, but if you hate the idea of computing the name of a standard callback function, a variation on the above scheme would give the dev access to an additional variable inside of the server-side reflex class called @callback. Before returning from their reflex method, they could set @callback (nil by default) to a string which would be the controller#method they want to be run after the DOM replace is completed.
So, there you have it: two legitimate approaches to defining optional client-side callbacks. Option one is by convention but less flexible. Option two is more specific. Having thought about both, I prefer option two because I don't like having to follow a naming convention and it would bother me if I needed to duplicate the same code for two different reflex actions.
What do you think?
from stimulus_reflex.
...override the StimulusReflexController with a custom controller
I've thought about this and will likely support an override when calling StimulusReflex.initialize
EDIT: I've got a PR for this now #37
I also agree that we need to provide more detail on the before/after:morph
callbacks. Will think on this a bit.
EDIT: I'm moderately confident that this can be accomplished without requiring changes to CableReady. CableReady assigns the config
to event.detail
, so I think we can attach additional metadata the options hash of the morph
call. This metadata can identify the StimulusController that triggered the morph. Long story short, I'm pretty sure I can support this without much additional effort.
from stimulus_reflex.
I just blinked and realized that you have a config.focusSelector switch in cable_ready.
I mean, this doesn't cover the general notion of callbacks but I'm impressed at how you anticipated this before I was even aware of the project. 🥇
from stimulus_reflex.
Latest now supports this feature. https://docs.stimulusreflex.com/lifecycle
from stimulus_reflex.
Related Issues (20)
- Controller over reflex attribute is ignore and reflex is always called with default StimulusReflexController HOT 7
- Broken Next Page Link on Welcome Page of Docs HOT 2
- HEAD and most of the latest releases are broken, references an undefined exception
- StimulusReflex is not compatible with the standalone ActionCable server HOT 9
- Wrong dataset getting from Docs example HOT 2
- NameError: undefined local variable or method `package_json' HOT 3
- Reflex not triggered when a Stimulus controller is also attached to a field HOT 4
- Form parse errors are not captured and reported back to front-end
- Drop Rails 5 and 6.0 support
- `solid_cache` seems to work as well as Rails cache store HOT 1
- Add full-stack tests
- Stimulus_reflex and esbuild error HOT 1
- OpenStruct no longer supported by json HOT 1
- Refactor away instances of OpenStruct
- NameError: uninitialized constant StimulusReflex::Installer::Thor when running rake tasks HOT 1
- Support `relative_url_root`
- Could not find generator 'stimulus_reflex:initializer'
- Unrecognized command "esbuild" (Rails::Command::UnrecognizedCommandError)
- Installer should work in CI (noninteractive) environment
- docs recommend hiredis gem along with incompatible redis version
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stimulus_reflex.