「JavaScript/Flash/HTML 5 でスパゲッティコードにならないためのモダン設計入門」写経

今更ですが、写経してみました。とはいっても、丸写しではなく仕様を理解した上で自分で考えながら*1。以前通して読んでるんで、まるっきり本誌の影響受けてないわけはないでしょうが。

第4章以降は、また後日時間取ってやってみようと思います。

合わせて読みたい:リッチWebアプリケーション作成のためのMVC - hayashi_77の日記

【追記】チェックボックスがクリックされるたびに該当部分のDOMが全クリア・全構築されてます。初期表示とクリック時の表示部分を同一化できる(drawIcecreams())のはいいのですが、パフォーマンス的によろしくないですね。布団に入りながら気づきました><

WEB+DB PRESS Vol.53

WEB+DB PRESS Vol.53

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Web+DB Vol.53 Example</title>
<script src="http://www.google.com/jsapi"></script>
<script>google.load("jquery", "1");</script>
<script src="mvc-example.js"></script>
</head>

<body>
<form action="post">
    <ul id="icecreams">
        <!-- アイスクリーム一覧 -->
    </ul>

    <div id="icecream-list">
        <!-- 選択されたアイスクリーム  -->
    </div>
</form>
</body>
</html>
// ----------------------- Model --------------------------- //
// アイスクリーム一覧
var icecreamModel = {
	list : [ {
		name : "バニラ"
	}, {
		name : "チョコチップ"
	}, {
		name : "オレンジ"
	}, {
		name : "チョコミント"
	}, {
		name : "ストロベリー"
	}, {
		name : "抹茶"
	} ],

	// アイスクリーム一覧を返す
	getList : function() {
		return this.list;
	},

	// 指定したIndexのアイスクリーム名を返す
	getName : function(i) {
		return this.list[i].name;
	}
};

// 選択されているアイスクリームの管理
var selectIcecreamModel = {
	list : [],

	// 選択されているアイスクリームを返す
	getList : function() {
		return this.list;
	},

	// 選択されているアイスクリームを更新する
	updateIcecream : function(i) {
		this.list.push(i);
		if (this.list.length > 2) {
			this.list.shift();
		}
	}
};

// ----------------------- View --------------------------- //
// アイスクリーム一覧 を表示する
function drawIcecreams() {
	$('#icecreams').empty();

	// アイスクリーム一覧を表示する
	var list = icecreamModel.getList();
	for ( var i = 0; i < list.length; i++) {
		var checkbox = $("<input type='checkbox'>").attr( {
			name : "icecreme",
			value : i
		}).click(function(event) {
			onclickIcecream(event);
		});
		var li = $("<li>").append(checkbox).append(list[i].name);

		$('#icecreams').append(li);
	}

	// 選択されているアイスクリームのチェックをオンにする
	var list = selectIcecreamModel.getList();
	for ( var i = 0; i < list.length; i++) {
		$('#icecreams li:eq(' + list[i] + ') input').attr("checked", "checked");
	}
}

// 選択されたアイスクリーム を表示する
function drawIcecremeList() {
	$('#icecream-list').empty();

	var list = selectIcecreamModel.getList();
	for ( var i = 0; i < list.length; i++) {
		$('#icecream-list').append(icecreamModel.getName(list[i]));
		$('#icecream-list').append(' > ');
	}
}

// ----------------------- Controler --------------------------- //
// アイスクリームがクリックされた時
function onclickIcecream(event) {
	selectIcecreamModel.updateIcecream(event.target.value);

	drawIcecreams();
	drawIcecremeList();
}

// DOM構築終了時
$(function() {
	drawIcecreams();
});

*1:それは、写経じゃないなw