Tuesday, January 15, 2013

ExtJS覚書 #1 Ext.data.ModelでREST


ExtJSでは、Ext.data.Modelを拡張したデータモデルをを使って、正しくRESTでJSONデータをやり取りする事できる。
データのライフサイクルまでそれなりに管理してくれていて便利ではあるが、何をしてくれるかを正しく理解する必要がある。
ここでは、モデルとフォーム(Ext.form.Panel)を使って一意のデータをCRUDする方法を説明する。

データモデル(Ext.data.Model)とCRUD

id, 姓, 名, 性別 という要素を持つEmployeeというデータをCRUDするRESTのクライアントの定義は以下のようになる。
idPropertyはこのデータモデルのIDとなるプロパティを指定する。
proxyのtypeに"rest"を指定することにより、Ext.data.proxy.Restが使われる。正しくRESTの型にはまる。

Ext.define('Employee', {
    extend : 'Ext.data.Model',
    idProperty : 'id',
    fields : [ 
        { name : 'id', type : 'string' },
        { name : 'firstName', type : 'string' },
        { name : 'lastName', type : 'string' },
        { name : 'gender', type : 'string' }
    ],
    proxy : {
        url : "/コンテキストルート/employeeService",
        type : "rest"
    }
});

データをロードする(loadメソッド)

このデータモデルを使ってデータをロードするコードは以下の通り。
var emp = Ext.ModelManager.getModel('Employee');
emp.load('123', {
        waitMsg : 'Loading...',
        success : function(record, operation){ },
        failure : function(record, operation){ }
        });

これで、 http://ホスト/コンテキストルート/employeeService/123 にGETリクエストが送られる。
success, failure関数の引数recordには、得られたデータ(Employeeのインスタンス)が入る。

データモデルをformにセットする

form(Ext.form.Basic)のloadRecord()を使って、データモデルをformにセットする事が出来る。
この時データモデルの内容で、formの要素は書きかえられる。
データモデルのfieldと、formの要素の名前(と型)が一致していればOK。
var emp = Ext.ModelManager.getModel('Employee');
emp.load('123', {
        waitMsg : 'Loading...',
        success : function(record, operation){
            empForm.getForm().loadRecord(record);
        },
        failure : function(record, operation){ }
        });

データを新規作成する(saveメソッド)

Ext.ModelManager.create()を使ってデータモデルを新規作成する。
save()メソッドでJSONデータをPOSTする。
var emp = Ext.ModelManager.create('Employee',{id : '123', firstName : 'Fidel', lastName : 'Castro', genger: 'male'});
emp.save({
        waitMsg : 'Saving...',
        success : function(record, operation){ },
        failure : function(record, operation){ }
        });

これで、 http://ホストコンテキストルート/employeeService に、JSONデータがPOSTされる。
success,failure時の関数の引数 record はにデータモデルのインスタンス、operationには、ext.data.Operationのインスタンスがセットされる。
ここで、setId()メソッドは使ってはならない。この件については『データを更新する』のセクションで説明する。
成功時、operationのconfig、"action"には"create"が入っている。

formのデータを使って新規作成する

フォームのデータを使って作る場合はExt.ModelManager.create()の第2引数をform.getValues()にすればよい。
formの要素と、データモデルのフィールドの名前と型は合わせておく。
var form = this.up('form').getForm();
var emp = Ext.ModelManager.create('Employee', empForm.getForm().getValues(false));
emp.save({
        waitMsg : 'Saving...',
        success : function(record, operation){
            empForm.getForm().loadRecord(record);
        },
        failure : function(record, operation){ }
        });

データを更新する(saveメソッド)

load()されたModelでsave()メソッドを使うとJSONデータがPUTされる。
この時のURLはproxyで設定したURLに"/id文字列"が付いたものになる。
上記の例で、idPropertyに設定したフィールド(デフォルトは"id")の値が"123"であった場合、
http://ホスト/コンテキストルート/employeeService/123
となる。
新規作成もsave()メソッドを使う、save()メソッドによってPOST(create)されるのかPUT(update)されるのかは、phantomというプロパティがtrueかどうかで決まる。trueならPOSTとなる。
このphantomというプロパティは、Modelのidプロパティ(デフォルトはid)に値が入っているかどうかで決まる。
model.setId(値);を実行するとphantomがfalseにセットされるようになっている。
どうもExt.data.Modelは、

  • idは一つ
  • idは新規作成時に付与される

というポリシーで作られている。
複合キーであったり、id(コード等)をユーザが決める場合はこの事を意識してプログラミングする必要がある。


formからデータモデルのインスタンスを取り出してPUTする

form(Ext.form.Basic)のgetRecord()を使って、formからModelのインスタンスを得る事が出来る。form.loadRecord()によってセットされているModelが得られる。
フォームにModelがロードされていない状態(loadRecord()されていないform)では、getRecord()はundefinedを返す。
ただし、ここで得られたrecordは、フォーム上での編集が反映されていない(編集前のデータが残っているということ)。
form(Ext.form.Basic)のupdateRecord()で、現在のフォームのデータを反映する事が出来る。

var emp = form.getRecord();    /* フォームよりデータモデルのインスタンスを得る */
form.updateRecord(emp);        /* 現在のフォーム上のデータでモデルの内容を更新する */
emp.save({
        waitMsg : 'Saving...',
        success : function(record, operation){ },
        failure : function(record, operation){ }
        });

成功時、operationのconfig、"action"には"update"が入っている。

データを削除する(destroy()メソッド) 

削除するコードは以下の通り。
var emp = Ext.ModelManager.getModel('Employee');
emp.set('123', 'Fidel', 'Castro', 'Male');
emp.destroy({
        waitMsg : 'Deleting...',
        success : function(operation){ },
        failure : function(operation){ }
        });

これで、 http://ホスト/コンテキストルート/employeeService/123 にDELETEリクエストが送られる。
saveと同様に、JSONデータが送られる。
123の部分には、データモデル定義のidPropertyに指定したフィールドの値がセットされる。

No comments:

Post a Comment