背景
JavaScriptにおけるMV*なフレームワークが色々出てくるが、往々にして、チュートリアルはToDoアプリであったりする。私も含めてだが、サンプル作成してるようなDeveloper連中なんて、本来そんなにToDo管理したがるようなタイプじゃないと思うのだけど、お前らどんだけToDo好きなんだ、と言いたい。
ただ、確かにToDoアプリは下記の要件を含むことになるので、HelloWorldの次には丁度良いのだろう。
- タスクの繰り返し表示(forEach的なもの)
- タスクの作成/表示/更新/削除(CRUD)
しかも1画面で完結するし、データ構造は簡単なので、MV*のうち、最も特色が出やすい*の説明をしやすいのだろう。
本題
背景が無駄に長くなった。
別にToDoアプリが多すぎることにケチ付けたい訳ではない。
作成したタスクの削除処理において、「配列から選択された要素をどうやって削除するか」という部分が面白いのだ。単純化すると、下記におけるremove関数の実装を作成しろ、と言っているのに等しいのだが、
var task1 = {}, task2 = {}, task3={}, tasks = [task1, task2, task3];
function remove(arr, target){
// remove(tasks, task2) の結果が[task1, task3]となるよう実装してください.
}
上記は(Ecma 5thでないブラウザまで含めて考えると)、実はあまり綺麗には書くことが出来ない。
Angularの場合はng-repeatディレクティブ中から$indexで要素番号が取得できるので、タスク削除は下記のようになる。
<div ng-controller="HogeCtrl">
<ul ng-repeat="item in someList">
<li class="task">{{item.name}}<button ng-click="remove($index)">remove</button></li>
</ul>
</div>
HogeCtrl.js
function HogeCtrl($scope){
$scope.someList = [
{name: 'foo'},
{name: 'bar'}
];
$scope.remove = function(i){
$scope.someList.splice(i, 1);
};
}
ToDoのタスク削除を例に説明したが、上記のように「ng-repeatループ中で、$indexをコントローラの引数に渡すパターンは、よく出てくるので覚えておいて損はないはず。
参考・補足
- http://todomvc.com/ は色々なMVC派生フレームワークによるToDoアプリがあるので、コードの比較ができる.
- Ecma 5thであっても、Array.indexOfは線形探索なので、最初からindexが使える方が高速。
- jQueryだったら下記ですね。
jQuery
$('li.task button').click(function(){
$(this).parents('.task').remove();
});