11.scheduleアプリ イベントハンドリング
イベントハンドリング
前回のチュートリアルで作成したScheduleModelとDailyScheduleModelは互いに連携をとって整合性を維持する必要があります。
ScheduleModelに新しく予定が登録された場合、その日付についてDailyScheduleModelにも登録しなければいけません。
データモデルのイベントハンドリング機構を使って、自動でデータの整合性を維持するようにします。
以下のように行います。
- DailyScheduleModelはユーザからの操作で、直接変更できないようにする。
- ScheduleModelの'itemsChange'イベントを拾って、その中でDailyScheduleModelへデータを登録・削除を行う。
ScheduleModelのitemsChangeイベントハンドラだけでDailySchedulesModelの操作を行うようにすることで、イベントハンドラを正しく記述さえすればDailySchedulesModelの整合性は保たれます。
イベントハンドラの実際のコードは以下のようになります。
// scheduleModelにデータが追加、削除、変更されたらdailySchedulesModelに反映させる
scheduleModel.addEventListener('itemsChange', function(ev) {
var manager = this.getManager();
// アップデートセッション開始
manager.beginUpdate();
// 新しく登録されたアイテムについて
for ( var i = 0, l = ev.created.length; i < l; i++) {
// 登録されたスケジュールの日付をキーに、スケジュールをDailySchedulesModelに登録する。
var item = ev.created[i];
if (dailySchedulesModel.has(item.get('date'))) {
// 既存の日付であれば、schedulesプロパティに追加する。
dailySchedulesModel.get(item.get('date')).get('schedules').push(item);
} else {
// 予定のない日への登録であれば、その日についてのデータアイテムを新規作成する
dailySchedulesModel.create({
date: item.get('date'),
schedules: [item]
});
}
}
// 削除されたアイテムについて
for ( var i = 0, l = ev.removed.length; i < l; i++) {
var item = ev.removed[i];
var date = item.get('date');
// 削除された予定が登録されていた日付のDailySchedulesModelのデータアイテムを取得
var dailyItems = dailySchedulesModel.get(date);
// schedulesを取得
var schedules = dailyItems.get('schedules');
// schedulesの何番目に削除されたスケジュールがあるか、を取得
var index = $.inArray(item, schedules);
if (index !== -1) {
// 削除された予定を、その日のschedulesから削除
schedules.splice(index, 1);
if (schedules.length === 0) {
// 該当日の予定がなくなったら、該当日のデータアイテムを削除
dailySchedulesModel.remove(date);
}
}
}
// アップデートセッションの終了
manager.endUpdate();
});
DailySchedulesModelのイベントハンドラ
予定のある日付、無い日付に変更があったら、カレンダーの予定ありマークを更新します。この処理は、DailySchedulesModelのイベントハンドラに記述します。
// スケジュールに変更があったら、予定のある日付リスト(daets)を更新
dailySchedulesModel.addEventListener('itemsChange', function(ev) {
for ( var i = 0, l = ev.created.length; i < l; i++) {
// dailySchedulesModelに新しく追加されたデータアイテムのID(日付)をdatesに追加
// この時にdatesのobserveイベントが発火する(コントローラでイベントリスナを定義している)
scheduleController.dates.push(ev.created[i].get('date'));
}
// ある日の予定がすべて削除されると、該当する日付をIDに持つアイテムが削除される。
for ( var i = 0, l = ev.removed.length; i < l; i++) {
// 削除された日付を予定のある日付リスト(dates)から削除
scheduleController.dates.splice($.inArray(ev.removed[i].get('date'), that.dates), 1);
}
});
// ScheduleController内 //
var that = this;
this.dates.addEventListener('observe', function(ev) {
// スケジュールの存在する日付に変更があった時のイベントリスナ
if (!ev.isDestructive) {
// 変更されている可能性がない(変更のないメソッド呼び出し)なら終了
return;
}
// 予定のある日付をマーキングするメソッドを呼び出す
that.plotExistScheduleMark();
});
イベントハンドラの流れを書くと、
- スケジュールを登録
- ScheduleModelのitemsChangeで、DailySchedulesModelを更新
- DailySchedulesModelのitemsChangeで、ScheduleController.datesを更新
- ScheduleController.datesのobserveで、予定あり日付をマーキングする(ビューへの反映)
となります。
データアイテムに変更があった際に、変更をビューへ反映させる方法は、イベントリスナを自分で書く他に、データバインドを使用する方法があります。
予定あり日付のマーキングの更新は、上記のようにイベントリスナを自分で書いて実装しています。が、予定を修正・追加・削除した際の、詳細ビュー(右側のタブ)では自動で変更が反映されるようにデータバインドを使用しています。
次の章では、データバインドを使ってビューへ変更を反映させる方法を説明します。
次のステップ ⇒ サンプルアプリ データバインド