モデルの状態を整理する – Ember.js入門(25)
渡辺です。
国内では話題性の乏しいEmber.jsですが、良質なチュートリアル(翻訳)が公開されていました(Ember.js - Webアプリケーションを正しく行う)。 Ember.js in Actionの著者のエントリーです。
さて、今回はモデルの永続化シリーズの最終回として、モデルの状態について整理して解説します。 ember-dataでは、クライアントサイドを意識したモデルの状態を考慮する必要があります。
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 |