高度なFormの実装(データバインディング)
最終更新
最終更新
前の章ではForm内の各input要素にJSからアクセスする方法をご紹介しました。
先程の例では "inputタグに入力された値をJSから取得する" という流れを説明しましたが、この逆の流れ、つまり "JSの値をinputタグに反映する" という事が出来ます。例を見てみましょう。
"Get random name" ボタンを押すと、入力欄に値が反映されます。これが "JSの値をinputタグに反映する" サンプルとなります。実際のコードを見ていきましょう。
HTMLには id="random"
なボタンを追加しました。他の箇所はほとんど変わっていません。
JSの方もデータ送信の流れ自体は変わっていませんが、細かい部分を見ていきましょう。
まずは let model = {}
にて、入力中のデータを保持するためのオブジェクト(以降モデル)を宣言しています。
続いてこの setName
関数でモデルの値の更新と、画面への反映( $name.val(model["name"]
= input要素のvalueの更新) を行っています。このようにモデルへのデータの保存処理と、UIの更新処理をまとめておくことで、モデル(Model)と画面(View)の表示がズレる(同期されなくなる)ことを防ぐことが出来ます。
このsetNameは以下の2箇所で呼び出されます。
$name.on("input", (event) => {...})
= これはinput要素自身にキーボードで文字が入力されるタイミングで発火されるイベントです。キーボード入力ごとにモデルのデータを更新しています。厳密にはsetName関数の内部でUIの更新を呼び出す = 重複した更新(元々input要素のUI更新は文字入力時に行われるので)になりますが、処理の流れをわかりやすくするためにこうしています。
$random.on("click", (event) => {...})
= これは "Get random name" ボタンを押した時の処理です。setName関数はinput要素にセットする値の文字列を引数として受け取るようになっているので、このように文字を渡すだけで画面に反映(= 再利用)できるようになっています。
最後の $form.on("submit", (event) => {...}
の箇所では以前のように $name.val()
としてinput要素の値を取得せずに、 model["name"]
としてモデル(JSのオブジェクト変数)の値を取得しています。こうすることで前者のDOMアクセス有りの場合($name.val()
)と比べてパフォーマンスが良いコード、かつデータの流れが整理されたコードになります。今回のような単一のinput要素の場合ではあまり恩恵を感じられないかもしれませんが、多くの入力欄があるページ(例: 注文・登録フォーム)では差が出てくるかと思います。
このような モデル(Model, データ = JSのオブジェクト)とビュー(UI, HTMLの要素) を分けて考える開発手法を MVVM(エムブイブイエム) と呼び、データ(モデル)とUI(ビュー/画面)を同期する仕組みを データバインディング(Data Binding/データの紐付け) と呼びます。ます。これはWebアプリケーションサーバの開発手法の一つである MVC(エムブイシー) と似た考え方です。MVVMを採用しているフレームワークの例としては Angular / Vue.js といったものが挙げられます。
Angular / Vue.js といったフレームワーク使うだけであれば、 MVVM の概念知らなくてもどうにかなるのですが、仕組みを詳しく理解しておきたい。という方はコラムで解説しているので、見てみてください。
次の章では今までの知識を活かして、簡単なカウンター(Counter/数字のカウント)を行うアプリを作っていこうと思います。