Giter Site home page Giter Site logo

Comments (4)

leastbad avatar leastbad commented on May 22, 2024

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.

hopsoft avatar hopsoft commented on May 22, 2024

...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.

leastbad avatar leastbad commented on May 22, 2024

I just blinked and realized that you have a config.focusSelector switch in cable_ready.

https://github.com/hopsoft/cable_ready/blob/561e5cee7e9bff1ea313d73b74d833c29622eb27/javascript/cable_ready.js#L29

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.

hopsoft avatar hopsoft commented on May 22, 2024

Latest now supports this feature. https://docs.stimulusreflex.com/lifecycle

from stimulus_reflex.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.