この記事はGoogle翻訳の結果を編集したものです。
最初のコントローラーを実装し、StimulusがHTMLをJavaScriptに接続する方法を学びました。 それでは、Basecampからコントローラーを再作成して、実際のアプリケーションで使用できるものを見てみましょう。
DOMクリップボードAPIのラッピング
BasecampのUIには次のようなボタンが散在しています。
これらのボタンのいずれかをクリックすると、BasecampはURLや電子メー アドレスなどのテキストをクリップボードにコピーします。
WebプラットフォームにはシステムクリップボードにアクセスするためのAPIがありますが、必要なことを行うHTML要素はありません。"クリップボードにコピー"ボタンを実装するにはJavaScriptを使用する必要があります。
コピーボタンの実装
PINを生成して他のユーザーにアクセスを許可できるアプリがあるとします。生成されたPINをボタンと一緒に表示して、簡単に共有できるようにクリップボードにコピーできれば便利です。
public/index.html
を開き<body>
の内容をボタンのラフスケッチに置き換えます。
<div>
PIN: <input type="text" value="1234" readonly>
<button>Copy to Clipboard</button>
</div>
コントローラーのセットアップ
次にsrc/controllers/clipboard_controller.js
を作成し、空のメソッドcopy()
を追加します。
// src/controllers/clipboard_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
copy() {
}
}
次に外側の<div>
にdata-controller="clipboard"
を追加します。この属性が要素に表示されるたびに、Stimulusはコントローラーのインスタンスを接続します。
<div data-controller="clipboard">
ターゲットの定義
クリップボードAPIを呼び出す前にその内容を選択できるように、テキストフィールドへの参照が必要です。テキストフィールドにdata-clipboard-target="source"
を追加します。
PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>
コントローラーにターゲット定義を追加して、テキストフィールド要素にthis.sourceTarget
としてアクセスできるようにします。
export default class extends Controller {
static targets = [ "source" ]
// ...
}
静的ターゲットラインとは何ですか?
Stimulusがコントローラークラスをロードするとき、target
と呼ばれる静的配列でターゲット名の文字列を探します。配列内のターゲット名ごとにStimulusは3つの新しいプロパティをコントローラーに追加します。ここで、"source"
ターゲット名は次のプロパティになります。
-
this.sourceTarget
はコントローラーのスコープ内の最初のsource
ターゲットに評価されます。source
ターゲットがない場合、プロパティにアクセスするとエラーがスローされます。 -
this.sourceTargets
は、コントローラーのスコープ内のすべてのsource
ターゲットの配列に評価されます。 -
this.hasSourceTarget
はsource
ターゲットがある場合はtrue
に評価され、そうでない場合はfalse
に評価されます。
ターゲットの詳細についてはリファレンスドキュメントを参照してください。
アクションの接続
これでコピーボタンを接続する準備が整いました。
ボタンをクリックしてコントローラーのcopy()
メソッドを呼び出す必要があるため、data-action="clipboard#copy"
を追加します。
<button data-action="clipboard#copy">Copy to Clipboard</button>
一般的なイベントには省略形のアクション表記があります
アクション記述子からclick->
を省略したことに気付いたかもしれません。これはStimulusがクリックを<button>
要素のアクションのデフォルトイベントとして定義しているためです。
他の特定の要素にもデフォルトのイベントがあります。 完全なリストは次のとおりです。
要素 | デフォルトイベント |
---|---|
a | click |
button | click |
details | toggle |
form | submit |
input | input |
input type=submit | click |
select | change |
textarea | input |
最後にcopy()
メソッドで入力フィールドの内容を選択し、クリップボードAPIを呼び出します。
copy() {
navigator.clipboard.writeText(this.sourceTarget.value)
}
ブラウザにページをロードし、コピーボタンをクリックします。 次にテキストエディターに戻って貼り付けます。PIN1234
が表示されます。
Stimulusコントローラーは再利用可能
これまで一度に1つのコントローラーのインスタンスがページ上にある場合に何が起こるかを見てきました。
ページ上にコントローラーの複数のインスタンスが同時に存在することは珍しくありません。たとえばPINのリストを表示し、それぞれに独自のコピーボタンを表示したい場合があります。
私たちのコントローラーは再利用可能です。テキストの一部をクリップボードにコピーする方法を提供したいときはいつでも、必要なのはページに適切な注釈を付けてマークアップすることだけです。
ページに別のPINを追加してみましょう。<div>
をコピーして貼り付け、2つの同一のPINフィールドが存在するようにし、2番目のvalue
属性を変更します。
<div data-controller="clipboard">
PIN: <input data-clipboard-target="source" type="text" value="3737" readonly>
<button data-action="clipboard#copy">Copy to Clipboard</button>
</div>
ページを再読み込みして、両方のボタンが機能することを確認します。
アクションとターゲットはあらゆる種類の要素に適用できます
次にPINフィールドをもう1つ追加しましょう。 今回はボタンの代わりにコピーリンクを使用します。
<div data-controller="clipboard">
PIN: <input data-clipboard-target="source" type="text" value="3737" readonly>
<a href="#" data-action="clipboard#copy">Copy to Clipboard</a>
</div>
Stimulusでは適切なdata-action
属性を持っている限り、必要なあらゆる種類の要素を使用できます。
この場合、リンクをクリックするとブラウザーもリンクのhref
をたどることになることに注意してください。アクションでevent.preventDefault()
を呼び出すことで、このデフォルトの動作をキャンセルできます。
copy(event) {
event.preventDefault()
navigator.clipboard.writeText(this.sourceTarget.value)
}
同様にsource
ターゲットは<input type="text">
である必要はありません。コントローラーはvalue
プロパティとselect()
メソッドを持つことだけを想定しています。 つまり、代わりに<textarea>
を使用できます。
PIN: <textarea data-clipboard-target="source" readonly>3737</textarea>
まとめと次のステップ
この章ではブラウザーAPIをStimulusコントローラーにラップする実際の例を見てきました。コントローラーの複数のインスタンスが一度にページに表示される方法を確認し、アクションとターゲットがHTMLとJavaScriptの疎結合を維持する方法を調べました。
次にコントローラーの設計を少し変更するだけで、より堅牢な実装につながる方法を見てみましょう。