Concepts fondamentaux
StimulusReflex permet de créer des interfaces utilisateur réactives en temps réel dans Rails grâce aux WebSockets (ActionCable) et CableReady.
Reflex de base
<!-- view.html.erb -->
<button data-reflex="click->Counter#increment">Increment</button>
# app/reflexes/counter_reflex.rb
class CounterReflex < ApplicationReflex
def increment
@count = element.dataset[:count].to_i + 1
end
end
Modes de Morph
Page Morph (Par défaut)
Rend à nouveau toute la page via l'action du contrôleur et applique les différences au DOM.
Selector Morph
# app/reflexes/example_reflex.rb
class ExampleReflex < ApplicationReflex
def update_metric
morph "#metric-display", render(partial: "metrics/metric", locals: { value: 42 })
end
end
Nothing Morph
Exécute la logique serveur sans modifier le DOM client.
class ExampleReflex < ApplicationReflex
def background_task
LongRunningJob.perform_later
morph :nothing
end
end
Méthodes du cycle de vie
Callbacks côté serveur
class ExampleReflex < ApplicationReflex
before_reflex :authenticate
around_reflex :measure_time
after_reflex :log_activity
end
Callbacks génériques côté client
beforeReflex(element, reflex, noop, reflexId): Avant l'envoi de la requête WebSocketreflexSuccess(element, reflex, noop, reflexId): Après l'exécution du reflex et mise à jour du DOMreflexError(element, reflex, error, reflexId): Quand le serveur lève une erreur non géréereflexHalted(element, reflex, noop, reflexId): Quand le reflex est interrompu parthrow :abortafterReflex(element, reflex, noop, reflexId): Exécuté en cas de succès comme d'échecfinalizeReflex(element, reflex, noop, reflexId): Hook de nettoyage final
Événements DOM
stimulus-reflex:beforestimulus-reflex:successstimulus-reflex:errorstimulus-reflex:haltedstimulus-reflex:afterstimulus-reflex:connectedstimulus-reflex:disconnectedstimulus-reflex:ready
Modèles pratiques
Gestion des formulaires
Les reflexes déclenchés sur des éléments de formulaire sérialisent automatiquement les champs dans params.
Chaînage de promesses
this.stimulate('Comments#create')
.then(() => this.showSuccess())
.catch((err) => this.handleError(err))
Éléments permanents
Marquez les éléments avec data-reflex-permanent pour que les morphs complets ne les écrasent pas.
<div data-reflex-permanent>
<video id="player" src="video.mp4" controls></video>
</div>