KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い
-
Upload
toshihiro-kawachi -
Category
Technology
-
view
1.763 -
download
0
description
Transcript of KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い
プロジェクトにMVVMを適用する狙い
KnockoutJS勉強会 2014年5月17日
自己紹介
中規模業務系Webシステムのリプレースプロジェクトを、従来型Webシステム+Ajaxで準備していたが、突然、SPAっぽくやることに。
クライアントサイドフレームワークを検討。
各種勉強会に出まくって情報収集
従来型とのハイブリッドでも適合しそうなKnockoutJSの採用を決定し準備。
現在、実装メンバーと合流し実装着手。
経緯
今回の趣旨
プロジェクトの方針説明的な
従来型Webからクライアントサイドにっ重心を移動した場合の構成について
ターゲット
「SPAっぽいのでやってよ」って突然振られそうな空気を感じている人
最近突然湧きあがったjQuery批判に戸惑いを隠せない人
私の今のプロジェクトに参加しそうな人
アジェンダ
KnockoutJSって何?
MVVM?
Webシステムの構成の変遷
手ごたえ
とは
JavaScriptのクライアントサイドフレームワーク
Microsoftの社員の一人がOSSとして開発そうな。MS製ではないが関連は深いとか。
MVVMのアーキテクチャパターンを採用
Ajax通信メインのSinglePageApplication/MultiPageApplicationを作りやすい
宣言型バインディングによるリアクティブプログラミングのスタイル
Model-Driven-View
Angular.js、Backbone.jsと比較
MVVMとは
アプリケーションをModel-View-ViewModelに分割するアプリケーションのアーキテクチャパターンの手法
Modelとは
定義としては、ドメイン領域のデータを具現化したオブジェクト。
Viewとは
可視化できる画面。データの入出力部分。
View-Modelの状態を常に画面に反映し続ける。
View-Modelとは
ModelとViewの橋渡し的存在。
ViewがModelのデータをViewからバインディングできるようにする役割。
(ボクが考える)MVVM概念図
• ViewはViewModelをデータバインディングで追従。• ViewModelを監視して、変更を自動的に反映する
• ViewModelはViewを知らない(依存しない)。Modelの情報を監視可能(Observable)な状態にして、外部(View)に提供する。
• Modelは他の存在を気にせず、依存もしない。• 主にビジネス領域のデータを格納するだけ。
データバインディングの例
価格:<input type=“text” data-bind=“value:price” id=“priceText”>
消費税率:<span data-bind=“text:taxRate” id=“taxSpan”> % <hr>
税込金額:<span data-bind=“text:taxIncluded” id=“taxIncludedSpan”> 円
1000価格:
8消費税率: %
税込金額: 1080 円
function SomeViewModel(){
this.price = ko.observable(1000);
this.taxRate = ko.observable(8);
this.taxInclude=ko.computed(function(){
return calcTaxRate(this.price,this.taxRate);
});
}
価格を2000にすると、税込金額は2160に変わる
data-binding
MVVMとデータバインディングのうまみ Viewからロジックを追い出せる。分離できる。
data-bindingでViewModelの変数やメソッドを指定するだけ
Viewのコントロール同士の連携をシンプルにできる。
Viewのレイアウト変更にロジックが影響を受けない。
処理の起点がView(DOM)にない。
ViewはViewModelを追いかけているだけ。
DOMはViewModelの変更を受けて勝手に変わる。そこがリアクティブ。
ViewModelの使いまわしが可能。
ViewModelはViewに依存しない。
Viewにデータを置かなくていい。
データはViewModelで管理して、最終的にModelに反映。
Ajax通信時にFormからJSONやQueryStringを組み立てる必要がない。
それがいろいろはかどる!
jQueryのオンリー構成
まず初めに対象のデータを選ぶDOMを選んでから処理を実行
$(“#price”).change(calcTaxInclude);
レイアウトが変わると、、、
val =
$(this).closest(“table”).children(“span.target”).text(“Changed!”);
いろいろはかどらなくなったり
UnitTestでブラウザが必須だったり
$(function(){
$document.on(”change”, “.target”,(function(e){…}));
});
とか、テストフレームワークでテストできないロジック書いてしまいがち。
例えば、こんな画面
製品マスタに構成部品を追加する。
「追加」で一覧に登録できれば「登録」で親子を一括登録し
たい。
従来型:ブラウザRequestで画面書き換え型
製品登録
製品情報退避
serv
er
clie
nt
追加
Session
部品追加画面
DB
製品登録
追加部品情報退避製品情報取り出し
永続化処理
追加 登録
一部Ajaxを取り入れたDOMベースのJavaScript活用型
製品登録
serv
er
clie
nt 追加
部品追加画面
DB永続化処理
登録
追加
$(“部品1”).data(“code”,”FRAME1000”)$(“部品2”).data(“code”,”TIRE1000”)$(“部品3”).data(“code”,”CMP1000”)
製品登録
<inupt type=“hidden” name=“部品1”><input type=“hidden” name=“部品2><input type=“hidden” name=“部品3>
POST/GET
OR
View
ViewModel
ViewMod
elViewMod
elViewMod
elModel
今回MVVM活用でのクライアントデータ保持型
製品登録
serv
er
clie
nt
追加 部品追加画面
DBDataAccess
登録
追加
{product:製品データ,
部品Array:[部品1,部品2,部品3,部品4,部品5]
}
Data-Bind
Ajax通信
(JSON)
jQueryとの連携 Ajax通信はKnockout範囲外でDeferred/Promiseを活用。
DOMを直接指定して操作するScriptは使わない。
ViewModelはViewのことは知らない。一方的に呼び出されるだけ。
jQueryのプラグインはどう使う?
バインディングの自作。カスタムバインディングの中で呼び出す。
カスタムバインディング中では、定義されているDOMがわかる。
Viewを動かすのはすべてKnockoutの範囲内にする?
ビジネスロジックに一切からまない見た目だけの処理はdocument.readyでベタに書くのもありかと。
マウスオーバーで表示領域を拡大するとか。
手応えメリット
ViewModel/ModelをそのままJSONとして投げられるのは楽
クライアント側のhiddenでデータ持ちまわす泥臭さがなくなった。
画面非表示になった削除対象キーも裏で保持しておける。
クライアント側で状態を持つため、複数Windowを開かれた場合の対応が楽
データと表示フォーマットの分離
Viewの責務をサーバー側から追い出すことができた。
和暦入出力の変換処理がサーバー側で不要になった。Model/ViewModelはDate⇔CustomBindingで和暦に変換⇔HTMLは和暦
悩みどころ
表示完了までのワンテンポのずれ
HTMLがロードされた後、ko.bidingContext時にDOMが動く。FOUCっぽい現象。現在調整中。
ありがとうございました