MVCな画面を書いてみる
お世話になっております。
ウェブDBプレスのvol.53には、「JavaScript/Flash/HTML5でスパゲッティコードにならないためのモダン設計入門」という特集があり、それを拝見したところ、自分で実装したくなったので書きました。
本に影響されてコードを書くのは久しぶりです。ちょうどこの夏にスパゲッティコードを生産してしまったせいでしょうか。
<html> <head> <style type="text/css"> #messageDiv span { border-bottom: solid 2px #9999FF; width: 300px; display: block; padding-top: 1px; } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> var G = { model:{ message: [], getMessage: function(){ return G.model.message; }, addMessage: function(msg){ var now = new Date(); G.model.message.push(now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + ': ' + msg); if(5 < G.model.message.size()){ G.model.message.shift(); } } }, update: { message: function(elm){ var messages = G.model.getMessage(); messages.each(function(msg, index){ elm.down('span', index % 5).update(msg); }); } }, handler: { onButtonClick: function(elm){ G.model.addMessage('click'); G.update.message(elm); } } } document.observe('dom:loaded', function(){ G.update.message($('messageDiv')); $('updateButton').observe('click', function(e){ e.stop(); G.handler.onButtonClick($('messageDiv')); }); }); </script> </head> <body> <div id="messageDiv"> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> </div> <form> <input id="updateButton" type="button" value="Button" /> </form> </body> </html>
ボタンをクリックすると、時刻を表示します。最大5件まで表示し、古いものから捨てていきます。機能としては、記事にあるものとほとんど同じです。
大きく分けると、「model, update, handler」の3つに分かれ、それぞれが「MVC」に対応しているイメージです。
以下、気になっている点を挙げておきます。
- handlerからupdateを実行しているが、初期処理でmodelへupdateを渡してしまったほうが、よりMVCらしい。
- modelのデータの持ち方は、文字列にするのではなく、時刻と文字列にわける。フォーマットはupdateで決める。
- 履歴の最大件数は、modelでもつべきか。
リッチな画面を作るには、JSP-Servlet-BeanなMVCだけでなく、JSPの中のMVCも設計しなければいけないようです。これは大変なことになってきました。
- 作者: 桜井雅史,縣俊貴,西田圭介,青木靖,川口耕介,井奥雄一,冨田慎一,森田創,鶴岡直也,長野雅広,武者晶紀,富士慶,中山大輔,常澤邦幸,山?賢,近藤裕介,稲葉健二,Elaine Gan,久保田慎之介,酒井三保子,吉野哲仁,井野貴亮,朝日勝雅,伊藤直也,ミック,高林哲,小飼弾,羽生章洋,角田直行,はまちや2,岡野原大輔,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2009/10/24
- メディア: 大型本
- 購入: 6人 クリック: 194回
- この商品を含むブログ (38件) を見る
以上
追記
Modelを強化しました。
<html> <head> <style type="text/css"> #messageDiv span { border-bottom: solid 2px #9999FF; width: 300px; display: block; padding: 2px; } #messageDiv { border: double 3px #9999FF; background-color: #FFFFDD; width: 304px; padding: 2px; } </style> <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript"> // beginning of MessageCollection var MessageCollection = Class.create({ initialize: function() { this.messages = []; this.maxMessageCount = 10; }, add: function(messageObj){ this.messages.push(messageObj); if(this.maxMessageCount < this.messages.size()){ this.messages.shift(); } this.update(); }, toArray: function() { return $A(this.messages); }, setUpdate: function(updateFunc){ this.update = updateFunc; } }); // end of MessageCollection // beginning of Message var Message = Class.create({ initialize: function(msg){ this.time = new Date(); this.message = msg; }, getTime: function(){ return this.time; }, getMessage: function(){ return this.message; } }); // end of Message var G = { model:{ messages: new MessageCollection(), getMessage: function(){ return G.model.messages.toArray(); }, addMessage: function(msg){ var messageObj = new Message(msg); G.model.messages.add(messageObj); } }, update: { message: function(){ var elm = $('messageDiv'); var messages = G.model.getMessage(); messages.each(function(messageObj, index){ var h = messageObj.getTime().getHours(); var m = messageObj.getTime().getMinutes(); var s = messageObj.getTime().getSeconds(); var msg = h + ":" + m + ":" + s + ":" + messageObj.getMessage(); elm.down('span', index % 10).update(msg); }); } }, handler: { onSendClick: function(elm){ G.model.addMessage($F('messageBox')); $('messageBox').setValue('') } } } document.observe('dom:loaded', function(){ G.model.messages.setUpdate(G.update.message); $('updateButton').observe('click', function(e){ e.stop(); G.handler.onSendClick($('messageDiv')); }); }); </script> </head> <body> <form> <div id="messageDiv"> <input id="messageBox" type="text" /> <input id="updateButton" type="button" value="Send" /> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> <span> </span> </div> </form> </body> </html>