Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
stimulus
Search
Shinichi Maeshima
October 16, 2018
Technology
4.7k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
stimulus
ginza.rb#64 でstimulusを紹介したときに使った資料です
https://ginzarb.doorkeeper.jp/events/81390
Shinichi Maeshima
October 16, 2018
More Decks by Shinichi Maeshima
See All by Shinichi Maeshima
メタプログラミングRuby問題集の活用
willnet
2
1.8k
rails g authenticationから学ぶRails8.0時代の認証
willnet
5
5.2k
What's a well-behaved Rails extension gem?
willnet
0
870
Sidekiq vs Solid Queue
willnet
15
15k
どうしてこうなった?から理解するActive Recordの関連の裏側
willnet
6
1.7k
Exceptional Rails
willnet
6
8.3k
Breaking the Flaky Test Cycle
willnet
2
2.4k
mrskで広がるインフラの選択肢
willnet
1
1.2k
アプリケーションを長期にわたって無理なく運用するためのたったひとつの方法
willnet
2
2.3k
Other Decks in Technology
See All in Technology
Rubyで音を視る
ydah
1
120
ポケモンの型をTypeScriptの型システムで表現してみた
subroh0508
0
350
サイバーセキュリティ概論 / Introduction to Cybersecurity
ks91
PRO
0
170
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
4
1.8k
社内 AI エージェント Synapse と セマンティックレイヤーの育て方
hiroakis
0
440
Djangoユーザが知っ得なPostgreSQL機能 - 設計の選択肢を増やす / Djang-use-PostgreSQL
soudai
PRO
0
210
サプライチェーンセキュリティの空白地帯 - 信頼できる”依存性”の未来を考える
rung
PRO
2
790
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
1
240
Rancherの紹介&Update情報(RancherJP Online Meetup #09)
yoshiyuki_kono
0
130
AIにフローを作らせようとして挫折した話
hamatsutaichi
0
230
自律型AIエージェントは何を破壊するのか
kojira
0
110
Mastering Ruby Box
tagomoris
3
150
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
200
Building Adaptive Systems
keathley
44
3k
The untapped power of vector embeddings
frankvandijk
2
1.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Typedesign – Prime Four
hannesfritz
42
3.1k
Producing Creativity
orderedlist
PRO
348
40k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
550
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
280
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
stimulus — ginza.rb#64 — @willnet
とは — Stimulus: A modest JavaScript framework for the HTML
you already have. — Basecamp製のJSフレームワーク — 現在のバージョン1.1.0(2018/8/23)
試用 — webpackなどでプリコンパイルするのを推奨 — cloneしてサッと試せるお試し用リポジトリがある — stimulusjs/stimulus-starter: A humble blank
slate for a modest JavaScript framework — rails使いなら rails new --webpack=stimulus yourappname でも環境作れるのでそっちでもよさそう — 公式チュートリアル的なのがあるので、それを見ながら手 を動かすとよいのでは
特徴 — react や vue.js とは志向がぜんぜん違う — データバインディングとかVirtual DOMとか、なにそれ 美味しいの?って感じ
— あくまでサーバが吐くHTMLと仲良くするためのフレーム ワーク — turbolinks friendly — サーバサイドの人が片手間でやるフロントエンドで、 vue.jsなどを導入する余裕がない…みたいなときに導入す るのが良いのでは、という気がする — 現行のjsを整理するために使う
どういうときに便利そうか — 通常RailsのJSはファイルごとにそれっぽく関数やイベント 登録などが整理されるけれど、特に強制力はない — なのでフラットにイベントが登録されたり、関数が登録 されたりする可能性がある — 例えば users.js
に user とあまり関係ない関数が 登録されたりする — DOMのclass属性とjsが紐付けられる事が多いけど、cssのた めに使うclassなのかjsで使うclassなのか分かりづらい — stimulusを使うとDOMに controller, target, action を割 り振ることができ、規約によって関数群を整理できる、と いうのがstimulusのキモの一つ(だと思う)
どういうときに便利そうか — turbolinksを使っているときに、特定のページでだけ実行 したい処理を書くのが面倒 — 特定のDOMがあるかチェックして、なかったらreturnす る、みたいな処理を毎回書く — だるい
こういうやつ $(document).on('ready turbolinks:load', () => { const target = $('.condition_transfer_on')
if (target.length === 0) { return } // .condition_transfer_on͕͋ͬͨ߹ͷॲཧ — stimulusを使うと「controllerがページ表示されたタイミ ング(connectされたタイミング)でなにか処理を実行する」 みたいなのが楽にかける
controller, target, action とは stimulus 公式のトップページを見ながら解説するとわかりや すそう Stimulus: A modest
JavaScript framework for the HTML you already have.
HTMLのコード <div data-controller="hello"> <input data-target="hello.name" type="text"> <button data-action="click->hello#greet"> Greet </button>
<span data-target="hello.output"> </span> </div>
jsのコード import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "name", "output" ] greet() { this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }
結果 名前を入力してGreet!をクリックすると、右側に名前を含んだ 文字列が出力される
HTMLとjsの対応付け — data-controllerの値とjsファイル名が紐付いている — data-actionの値とメソッドが紐付いている — data-targetの値とstatic targets = []
で定義された値が 紐付いている — static targets = ["name"] などとすると、 this.nameTarget でDOMの要素を扱うことができるよう になる
stimulusの大まかな機能は これだけ
完?
それぞれもうちょっと詳し く
controller — html中のdata-controllerに合わせて、紐付いた名前の controllerをインスタンス化し、DOMと紐づけてくれる — 例えば<div data-controller="hello"> であれば hello-controller.jsが自動的に読み込まれる —
ファイル名にアンダースコアを使うこともできる — date_picker_controller.js -> date-picker — 参考: https://stimulusjs.org/handbook/ installing#controller-filenames-map-to- identifiers
複数のコントローラを一つのDOMに紐付けること ができる <div data-controller="clipboard list-item"></div>
コントローラを複数のDOMに紐付けることができ る <ul> <li data-controller="list-item">One</li> <li data-controller="list-item">Two</li> <li data-controller="list-item">Three</li> </ul>
li要素それぞれに、別々のコントローラのインスタンスが割り 当てられる
action <div data-controller="gallery"> <button data-action="click->gallery#next">…</button> </div> — イベントの名前(click) — コントローラ名(garraly)
— アクション名(next) をそれぞれ指定する
eventオブジェクト actionとして定義されたメソッドに、eventオブジェクトが引 数として渡ってくる import { Controller } from "stimulus" export
default class extends Controller { next(event) { // … } }
eventオブジェクト — event.type でなんのイベントなのかが返る(例: 'click') — event.targetでどのDOM発祥なのか返る — event.currentTargetでイベントリスナが登録されている DOMが返る
イベントの名前 — DOM要素によっては省略できる — 例えばa要素ならclickがデフォルトで省略可能
同じDOMに複数イベント登録できる <input type="text" data-action="focus->field#highlight input->search#update">
target Action以外のDOMとjsの紐づけはtargetでやる
html <div data-controller="search"> <input type="text" data-target="search.query"> <div data-target="search.errorMessage"></div> <div data-target="search.results"></div>
</div> controller໊.target໊ で指定する
js import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "query", "errorMessage", "results" ] // … } — statis targets に配列でtargetになる要素の名前を渡す — すると後述のプロパティが生える
プロパティ 例えばqueryという名前のtargetを指定すると次のプロパティ が自動で生える — this.queryTarget — 最初にマッチしたDOMが返る — this.queriesTarget —
マッチしたDOMが全部返る — this.hasQueryTarget — DOMが存在しているのかbooleanで返る
一つのDOMに複数のtargetを指定できる <form data-controller="search checkbox"> <input type="checkbox" data-target="search.projects checkbox.input"> <input type="checkbox"
data-target="search.messages checkbox.input"> … </form>
Data Maps <div data-controller="content-loader" data-content-loader-url="/messages"> </div> — 状態をどこで持つのか、という話 — 他のjsフレームワークはjsで持つけど、stimulusjsはDOMで
持つ — html側からjs(その逆も)になにかデータを渡すとき、data- ίϯτϩʔϥ໊-σʔλ໊で渡すというのがstimulusjsでの お作法
js // controllers/content_loader_controller.js import { Controller } from "stimulus" export
default class extends Controller { connect() { fetch(this.data.get("url")).then(/* … */) } } — this.data.get("url")でdata-content-loader-urlの値を取 得できる
その他のメソッド — this.data.set(key, value) — DOMの方にデータを設定する — this.data.has(key) — booleanで、そのkeyのdataが存在しているのか返す
— this.data.delete(key) — keyに紐づくdataを消す
注意点 — dataはNumberでアサインしても、getするとStringで返って くる — とくに型変換とかはしてないもよう this.data.set("count", 1) this.data.get("count") //
"1"
Lifecycle Callback controllerのインスタンスがDOMに割り当てられたときなどに hookしてメソッド実行をさせることができる import { Controller } from "stimulus"
export default class extends Controller { connect() { // … } }
メソッド — initialize — controllerのインスタンスが作られたタイミング — connect — DOMに紐付いたタイミング —
ドキュメント上にdata-controllerを持つDOMが現れたら connectされる — disconnect — DOMとの紐づけがなくなったタイミング — data-controllerを持つDOMが消されたり、data- controller属性自体が消されたりしたらdisconnect
DOMが存在する/しないで自動でcontrollerが紐付けられるというのが — turbolinksフレンドリーってことっぽい?
インスタンスは使い回される — disconnectしたあとにまたconnectされるケースでは、イン スタンスが使い回される — つまりconnectやdisconnectは複数回呼ばれる可能性が ある
まとめ
メリット — 学習コストがめっちゃ低い — 一日あれば使えるようになるのでは? — vannilajsやjQueryで作っているサービスから移行しやすい — 試してみた結果やめたくなった場合も比較的やめやすそう
デメリット — vannilajsから移行しても「単にメソッドやイベントを整理 した」以上にはならない — マジカルな何かですごいことになる、ということはない — できることが限定的 — SPAとか無理(そういうのはturbolinks使って擬似的にや
ればいいじゃん、という考え) — JSON APIを叩いて云々、とかは考えてない — クライアントサイドでDOMを組み立てる、なんて大変で しょ?全部HTMLでやればいいんだよ
以上