3

StimulusReflex cheatsheet

 2 years ago
source link: https://devhints.io/stimulus-reflex
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
StimulusReflex cheatsheet

via Data Attributes

Trigger reflexes without writing any javascript with the data-reflex attribute.

<!-- index.html.erb -->
<a
  href="#"
  data-reflex="click->CounterReflex#increment"
  data-step="1"
  data-count="<%= @count.to_i %>"
  >Increment <%= @count.to_i %></a
>
# counter_reflex.rb
class CounterReflex < StimulusReflex::Reflex
  def increment
    @count = element.dataset[:count].to_i + element.dataset[:step].to_i
  end
end

from Stimulus.js Controller

Stimulus.js controllers registered with StimulusReflex can use the stimulate method to trigger reflexes

<!-- index.html.erb -->
<a href="#"
  data-controller="counter"
  data-action="click->counter#increment"
>Increment <%= @count %></a>
// counter_controller.js
import { Controller } from 'stimulus'
import StimulusReflex from 'stimulus_reflex'

export default class extends Controller {
  connect() {
    StimulusReflex.register(this)
  }

  increment(event) {
    event.preventDefault()
    this.stimulate('Counter#increment', 1)
  }
}
# counter_reflex.rb
class CounterReflex < StimulusReflex::Reflex
  def increment(step = 1)
    session[:count] = session[:count].to_i + step
   end
end

#Morphs

Selector morphs

Instead of refreshing the entire page, you can specify a portion of the page to update with morph(selector, content)

<!-- show.html.erb -->
<header data-reflex="click->Example#change">
  <%= render partial: "path/to/foo", locals: {message: "Am I the medium or the massage?"} %>
</header>
<!-- _foo.html.erb -->
<div id="foo">
  <span class="spa"><%= message %></span>
</div>
# example_reflex.rb
class ExampleReflex < ApplicationReflex
  def change
    morph "#foo", "Your muscles... they are so tight."
  end
end

Nothing morph

Use morph :nothing in reflexes that do something on the server without updating the client.

# example_reflex.rb
class ExampleReflex < ApplicationReflex
  def change
    LongRunningJob.perform_later
    morph :nothing
  end
end

#Lifecycle

Server-side callbacks

Reflex classes can use the following callbacks. Full Docs

  • before_reflex
  • around_reflex
  • after_reflex

Client-side callbacks (generic)

StimulusReflex controllers automatically support five generic lifecycle callback methods.

  • beforeReflex(element, reflex, noop, reflexId) prior to sending a request over the web socket
  • reflexSuccess(element, reflex, noop, reflexId) after the server side Reflex succeeds and the DOM has been updated
  • reflexError(element, reflex, error, reflexId) whenever the server side Reflex raises an error
  • reflexHalted(element, reflex, noop, reflexId) reflex canceled with throw :abort in the before_reflex callback
  • afterReflex(element, reflex, noop, reflexId) after both success and error
  • finalizeReflex(element, reflex, noop, reflexId) after both success and error

Client-side callbacks (custom)

StimulusReflex controllers can define up to five custom lifecycle callback methods for each Reflex action. These methods use a naming convention based on the name of the Reflex. e.g. for the add_one reflex:

  • beforeAddOne(element, reflex, noop, reflexId)
  • addOneSuccess(element, reflex, noop, reflexId)
  • addOneError(element, reflex, error, reflexId)
  • addOneHalted(element, reflex, noop, reflexId)
  • afterAddOne(element, reflex, noop, reflexId)
  • finalizeAddOne(element, reflex, noop, reflexId)

Client-side events

If you need to know when a Reflex method is called, but you’re working outside of the Stimulus controller that initiated it, you can subscribe to receive DOM events

  • stimulus-reflex:before
  • stimulus-reflex:success
  • stimulus-reflex:error
  • stimulus-reflex:halted
  • stimulus-reflex:after

There are also events related to the StimulusReflex library setting up and connecting to ActionCable

  • stimulus-reflex:connected
  • stimulus-reflex:disconnected
  • stimulus-reflex:rejected
  • stimulus-reflex:ready

#Helpful tips

Forms

If a Reflex is called on a form element - or a child of that form element - then the data for the whole form will be properly serialized and made available to the Reflex action method as the params accessor. Read more

Promises

stimulate() method returns a promise

this.stimulate('Comments#create')
  .then(() => this.doSomething())
  .catch(() => this.handleError())

Inheriting data-attributes from parent elements

You can use the data-reflex-dataset="combined" directive to scoop all data attributes up the DOM hierarchy and pass them as part of the Reflex payload.

<!-- new.html.erb -->
<div data-post-id="<%= @post.id %>">
  <div data-category-id="<%= @category.id %>">
    <button data-reflex="click->Comment#create" data-reflex-dataset="combined">Create</button>
  </div>
</div>
# comment_reflex.rb
class CommentReflex < ApplicationReflex
  def create
    puts element.dataset["post-id"]
    puts element.dataset["category-id"]
  end
end

Reflex root

Instead of updating your entire page, you can specify exactly which parts of the DOM will be updated using the data-reflex-root attribute. Full docs

<!-- index.html.erb -->
<div data-reflex-root="[forward],[backward]">
  <input type="text" value="<%= @words %>" data-reflex="keyup->Example#words">
  <div forward><%= @words %></div>
  <div backward><%= @words&.reverse %></div>
</div>
# example_reflex.rb
  def words
    @words = element[:value]
  end

Permanent elements

Add data-reflex-permanent to any element in your DOM, and it will be left unchanged by full-page Reflex updates and morph calls that re-render partials.

<!-- index.html.erb -->
<div data-reflex-permanent>
  <iframe src="https://ghbtns.com/github-btn.html?user=hopsoft&repo=stimulus_reflex&type=star&count=true" frameborder="0" scrolling="0" class="ghbtn"></iframe>
  <iframe src="https://ghbtns.com/github-btn.html?user=hopsoft&repo=stimulus_reflex&type=fork&count=true" frameborder="0" scrolling="0" class="ghbtn"></iframe>
</div>

Aborting a reflex

call raise :abort within a reflex method to cancel it.

# comment_reflex.rb
class CommentReflex < ApplicationReflex
  def create
    raise :abort
  end
end

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK