モデルの状態を整理する – Ember.js入門(25)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。

国内では話題性の乏しいEmber.jsですが、良質なチュートリアル(翻訳)が公開されていました(Ember.js - Webアプリケーションを正しく行う)。 Ember.js in Actionの著者のエントリーです。

さて、今回はモデルの永続化シリーズの最終回として、モデルの状態について整理して解説します。 ember-dataでは、クライアントサイドを意識したモデルの状態を考慮する必要があります。

ember-data-conditions

New

モデルはstoreのcreateRecordメソッドで作成します。 モデルが作成され、saveされるまでモデルはNewとなります。

New状態はisNewプロパティがtrueとなることで確認出来ます。

var item = store.createRecord('item');
item.get('isNew');  // true

item.save().then(function(item) {
  item.get('isNew');  // false
});

New状態のモデルは、クライアントサイドのみにオブジェクトが存在し、サーバサイドに登録されていない状態です。 サーバサイドにモデルを登録するには、saveメソッドを実行し、RESTful APIの実行に成功しなければなりません。

Dirty

モデルにクライアントサイドで変更が加えられ、サーバサイドに反映されていない場合、Dirtyとなります。 モデルが新規に作成された場合についても同様にDirtyです。

Dirty状態はisDirtyプロパティがtrueとなることで確認出来ます。

var newItem = store.createRecord('item');
newItem.get('isDirty');  // true

var item = store.find('item', 1).then(function(item){
  item.get('isDirty'); // false
  item.set('name', 'XXX');
  item.get('isDirty'); // true
});

New状態のモデルは、クライアントサイドのみにオブジェクトが存在しているかクライアントサイドのみで変更が行われており、サーバサイドに反映されていない状態です。 サーバサイドにモデルを反映するには、saveメソッドを実行し、RESTful APIの実行に成功しなければなりません。

Deleted

モデルがクライアントサイドで削除状態となっている、すなわちdeleteRecordが呼び出され、サーバサイドに反映されていない場合、Deletedとなります。

Deleted状態はisDeletedプロパティがtrueとなることで確認出来ます。

var item = store.find('item', 1).then(function(item){
  item.get('isDeleted'); // false
  item.deleteRecord();
  item.get('isDeleted'); // true
  item.save().then(function(saved) {
    saved.get('isDeleted'); // true
  });
});

Loading, Reloading, Saving

モデルの読み込みや保存を行っている途中では、Loading, Reloading, Savingとなります。 これらの状態をスクリプトで取得してハンドリングすることはあまりありませんが、 Viewで「読み込み中」「保存中」といった状態をユーザに通知するためには有効です。

{{if loading}}<p>Now Loading…</p>{{/if}}

その他の状態

他の状態としてError, Loadedといった状態がありますが、基本的なモデルのライフサイクルとは関係がないため割愛します。

まとめ

Ember.jsでは、クライアントサイドでのモデルの状態を意識し、明示的にsaveメソッドなどを実行することで、サーバサイドと同期を行う必要があります。 自動的に行われれば便利かも知れませんが、何時どのタイミングで同期するのか?失敗した場合の処理をどうすれば良いのか?と、状態の変更に伴う処理は複雑です。明示的なタイミング(例:保存ボタン、画面遷移)でsave処理を行う方がシンプルなコードとなるでしょう。

最後にテーブル形式で状態をまとめます。

isNew isDirty isDeleted
作成後 true true false
取得時 false false false
プロパティ変更 false true false
プロパティ変更/save false false false
プロパティ変更/rollback false false false
delete false true true
delete/save false false true