【JavaScript】 大岡裁き勉強会でMVCモデルに沿ったソースの拡張をしてみた。

こんにちは。
Web系エンジニアの竹石です。

コツコツ進めることが好きな僕は、社内の勉強会に参加して
日々、技術の勉強をしています。

社内で技術系の勉強会は今、一つしかないんですが今日はその勉強会を
紹介したいと思います。

その名も【大岡裁き勉強会】

全然技術っぽくないどころか、何をするか全くイメージできないですが
技術の勉強会です。

以前はSeasar2を扱っていましたが、現在はJavascriptの勉強をしています。

基本的なDOMの使い方から、拡張しやすいソースの書き方まで
現場で使える技術が学べちゃいます。

今回のテーマは「MVCモデルに沿ったソースの拡張」

こんなhtmlがあって、view用のjsを作ってボタンを押したら、
ボタンのラベルのオプションが追加される機能を追加するというお題でした。

odai

ちなみに、コントローラーとモデルのjsは用意されています。

/**
* Controllerオブジェクトです。
* ModelとViewを関連付けます。
*/
(function() {
var Controller = {
/**
* 初期処理です。
* 対象のModelに以下メンバを追加します。
* container: ViewメンバMixin用オブジェクト
* addEventListener: Viewのイベントリスナを登録するメソッド
* dispatchEvent: addEventListenerで登録したイベントをディスパッチするメソッド
*
* @param model 対象のModel
*/
init: function(model) {
  model.container = {};
  model.addEventListener = this.addEventListener;
  model.dispatchEvent = this.dispatchEvent;
},
/**
* イベントリスナ追加処理です。
* Modelイベントのハンドラとして、Viewのメソッドを登録します。
*
* @param handler ハンドラ
* @param view 対象のView
*/
addEventListener: function(handler, view) {
  if (this.container[handler] == null) {
    this.container[handler] = [];
  }
  this.container[handler].push(view);
},
/**
* イベントのディスパッチ処理です。
* ModelのイベントをViewのハンドラに通知します。
*
* @param handler ハンドラ
*/
dispatchEvent: function(handler) {
  var args = [];
  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]);
  }
  this.container[handler].forEach(function(value) {
    value[handler].apply(value, args);
  });
 }
};
window.Controller = Controller;
})();
/**
* Model関数です。
* Viewで利用するTODOリストのデータを保持します。
*/
(function() {
/**
* コンストラクタです。
* 以下プロパティを保持します。
* text: TODOの内容
* complete: TODOが完了したかを判定するフラグ
*
* @param text TODOの内容
*/
var Todo = function(text) {
  this.text = text;
  this.complete = false;
};
/**
* completeを設定します。
* プロパティ設定後に、イベントをディスパッチします。
*
* @param complete TODOが完了したかを判定するフラグ
*/
Todo.prototype.setComplete = function(complete) {
  this.complete = complete;
  this.dispatchEvent('changeComplete');
};
// ControllerのMixin
Controller.init(Todo);
Controller.init(Todo.prototype);
// 各TODOのインスタンスを保持する配列
Todo.list = [];
/**
* TODOインスタンスの追加処理です。
* リストにインスタンスを格納後、イベントをディスパッチします。
*
* @param text TODOの内容
*/
Todo.add = function(text) {
  var todo = new Todo(text);
  Todo.list.push(todo);
  Todo.dispatchEvent('add', todo);
};
window.Todo = Todo;
})();

まず、view-usuallist.jsというjsを新規作成し、クラスを作ります。

(function() {
  var UsualListArea = function(id) {
};
window.UsualListArea = UsualListArea;
})();

次に、そのクラスの中の処理を書きます。

ポイントとしては、childNodesにはソースの改行のTextNodeも入ってくるので、
nodeTypeがdocument.ELEMENT_NODEのモノだけイベントを追加するところです。

※childNodesじゃなくて、childrenでとれば不要ですが。

(function() {
  var UsualListArea = function(id) {
  $usualLists = document.getElementById(id).childNodes;
  for (var i = 0; i < $usualLists.length; i++) {
    if ($usualLists[i].nodeType == document.ELEMENT_NODE) {
$usualLists[i].addEventListener('click', this.onClickHandler, false);
}
}
};
window.UsualListArea = UsualListArea;
})();

そして、イベント時にmodelにあるオプションを追加するファンクションを呼びます。

(function() {
 var UsualListArea = function(id) {
  $usualLists = document.getElementById(id).childNodes;
  for (var i = 0; i < $usualLists.length; i++) {
   if ($usualLists[i].nodeType == document.ELEMENT_NODE) {
    $usualLists[i].addEventListener('click', this.onClickHandler, false);
   }
  }
 };
 UsualListArea.prototype.onClickHandler = function(e) {

  Todo.add(this.firstChild.nodeValue);
 };
 window.UsualListArea = UsualListArea;
})();

最後にオンロード時にインスタンスを作るようにします。

window.onload = function() {
new AddItem('todoText', 'addItem');
new AddItemArea('addItemArea');
new UsualListArea('usualListArea'); ←追加
};

コレで、ボタンを押したら、そのボタンのラベルがオプションとして追加できるようになりました。

result

実は、この次のお題もありましたが、今日はこのくらいで。

コメントを残す

メールアドレスが公開されることはありません。

ABOUTこの記事をかいた人

アバター

WEBアプリ開発をメイン業務としている。後輩エンジニアの育成リーダーとしても活躍中。社内勉強会の立ち上げなど、会社の前線でその能力を発揮している。2009年、株式会社ヘッドウォータース新卒入社。