KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

20
プロジェクトにMVVMを適用する 狙い KnockoutJS勉強会 2014517

description

knockoutjsハンズオン勉強会 – 2014/05/17 – Microsoft 品川での発表資料です。

Transcript of KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

Page 1: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

プロジェクトにMVVMを適用する狙い

KnockoutJS勉強会 2014年5月17日

Page 2: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

自己紹介

Page 3: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

中規模業務系Webシステムのリプレースプロジェクトを、従来型Webシステム+Ajaxで準備していたが、突然、SPAっぽくやることに。

クライアントサイドフレームワークを検討。

各種勉強会に出まくって情報収集

従来型とのハイブリッドでも適合しそうなKnockoutJSの採用を決定し準備。

現在、実装メンバーと合流し実装着手。

経緯

Page 4: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

今回の趣旨

プロジェクトの方針説明的な

従来型Webからクライアントサイドにっ重心を移動した場合の構成について

Page 5: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

ターゲット

「SPAっぽいのでやってよ」って突然振られそうな空気を感じている人

最近突然湧きあがったjQuery批判に戸惑いを隠せない人

私の今のプロジェクトに参加しそうな人

Page 6: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

アジェンダ

KnockoutJSって何?

MVVM?

Webシステムの構成の変遷

手ごたえ

Page 7: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

とは

JavaScriptのクライアントサイドフレームワーク

Microsoftの社員の一人がOSSとして開発そうな。MS製ではないが関連は深いとか。

MVVMのアーキテクチャパターンを採用

Ajax通信メインのSinglePageApplication/MultiPageApplicationを作りやすい

宣言型バインディングによるリアクティブプログラミングのスタイル

Model-Driven-View

Angular.js、Backbone.jsと比較

Page 8: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

MVVMとは

アプリケーションをModel-View-ViewModelに分割するアプリケーションのアーキテクチャパターンの手法

Modelとは

定義としては、ドメイン領域のデータを具現化したオブジェクト。

Viewとは

可視化できる画面。データの入出力部分。

View-Modelの状態を常に画面に反映し続ける。

View-Modelとは

ModelとViewの橋渡し的存在。

ViewがModelのデータをViewからバインディングできるようにする役割。

Page 9: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

(ボクが考える)MVVM概念図

• ViewはViewModelをデータバインディングで追従。• ViewModelを監視して、変更を自動的に反映する

• ViewModelはViewを知らない(依存しない)。Modelの情報を監視可能(Observable)な状態にして、外部(View)に提供する。

• Modelは他の存在を気にせず、依存もしない。• 主にビジネス領域のデータを格納するだけ。

Page 10: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

データバインディングの例

価格:<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に変わる

Page 11: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

data-binding

Page 12: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

MVVMとデータバインディングのうまみ Viewからロジックを追い出せる。分離できる。

data-bindingでViewModelの変数やメソッドを指定するだけ

Viewのコントロール同士の連携をシンプルにできる。

Viewのレイアウト変更にロジックが影響を受けない。

処理の起点がView(DOM)にない。

ViewはViewModelを追いかけているだけ。

DOMはViewModelの変更を受けて勝手に変わる。そこがリアクティブ。

ViewModelの使いまわしが可能。

ViewModelはViewに依存しない。

Viewにデータを置かなくていい。

データはViewModelで管理して、最終的にModelに反映。

Ajax通信時にFormからJSONやQueryStringを組み立てる必要がない。

それがいろいろはかどる!

Page 13: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

jQueryのオンリー構成

まず初めに対象のデータを選ぶDOMを選んでから処理を実行

$(“#price”).change(calcTaxInclude);

レイアウトが変わると、、、

val =

$(this).closest(“table”).children(“span.target”).text(“Changed!”);

いろいろはかどらなくなったり

UnitTestでブラウザが必須だったり

$(function(){

$document.on(”change”, “.target”,(function(e){…}));

});

とか、テストフレームワークでテストできないロジック書いてしまいがち。

Page 14: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

例えば、こんな画面

製品マスタに構成部品を追加する。

「追加」で一覧に登録できれば「登録」で親子を一括登録し

たい。

Page 15: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

従来型:ブラウザRequestで画面書き換え型

製品登録

製品情報退避

serv

er

clie

nt

追加

Session

部品追加画面

DB

製品登録

追加部品情報退避製品情報取り出し

永続化処理

追加 登録

Page 16: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

一部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

Page 17: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

View

ViewModel

ViewMod

elViewMod

elViewMod

elModel

今回MVVM活用でのクライアントデータ保持型

製品登録

serv

er

clie

nt

追加 部品追加画面

DBDataAccess

登録

追加

{product:製品データ,

部品Array:[部品1,部品2,部品3,部品4,部品5]

}

Data-Bind

Ajax通信

(JSON)

Page 18: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

jQueryとの連携 Ajax通信はKnockout範囲外でDeferred/Promiseを活用。

DOMを直接指定して操作するScriptは使わない。

ViewModelはViewのことは知らない。一方的に呼び出されるだけ。

jQueryのプラグインはどう使う?

バインディングの自作。カスタムバインディングの中で呼び出す。

カスタムバインディング中では、定義されているDOMがわかる。

Viewを動かすのはすべてKnockoutの範囲内にする?

ビジネスロジックに一切からまない見た目だけの処理はdocument.readyでベタに書くのもありかと。

マウスオーバーで表示領域を拡大するとか。

Page 19: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

手応えメリット

ViewModel/ModelをそのままJSONとして投げられるのは楽

クライアント側のhiddenでデータ持ちまわす泥臭さがなくなった。

画面非表示になった削除対象キーも裏で保持しておける。

クライアント側で状態を持つため、複数Windowを開かれた場合の対応が楽

データと表示フォーマットの分離

Viewの責務をサーバー側から追い出すことができた。

和暦入出力の変換処理がサーバー側で不要になった。Model/ViewModelはDate⇔CustomBindingで和暦に変換⇔HTMLは和暦

悩みどころ

表示完了までのワンテンポのずれ

HTMLがロードされた後、ko.bidingContext時にDOMが動く。FOUCっぽい現象。現在調整中。

Page 20: KnockoutJS勉強会 プロジェクトにmvvmを適用する狙い

ありがとうございました