03.ディスクリプタの書き方
hifiveのデータモデルにおける「ディスクリプタ」とは、データモデルの名前、このデータモデルに属する各データアイテムがどのようなプロパティを持っているか、またそのプロパティにはどのような型・制約があるか、などを記述したものです。
データベースにおけるスキーマ定義と似たようなものです。
データモデルを作成する時には、このディスクリプタを指定する必要があります。
なお、ディスクリプタの詳細な仕様は「リファレンス(仕様詳細) » ディスクリプタ」をご覧ください。
ディスクリプタの基本的な書き方
ディスクリプタは、オブジェクトの形で定義します(以降このオブジェクトを「ディスクリプタオブジェクト」と呼びます)。
データモデル生成時は、このオブジェクトを引数として渡します。
1つのディスクリプタオブジェクトには、1つのデータモデルについての定義を記述できます。
ディスクリプタオブジェクトは以下のように記述します。
name: 'SampleDataModel', // データモデルの名前(必須)
schema: {...} // データアイテムのプロパティ定義(スキーマオブジェクト、必須)
};
// 記述したディスクリプタオブジェクトを基にデータモデルを作成
var model = sample.dataManager.createModel(descriptor);
このデータモデルに属するデータアイテムのプロパティ定義は、スキーマオブジェクト(上記schemaプロパティ)に記述します。
データアイテムのプロパティ定義(スキーマ)の基本的な書き方
このデータモデルに属する各データアイテムがどのようなプロパティを持つかは、スキーマオブジェクトで定義します。
スキーマオブジェクトは、先の例の通り、ディスクリプタオブジェクトのschemaプロパティにセットします。
スキーマオブジェクトには、データモデルに定義するプロパティとその定義を以下のように記述します。
プロパティ名1: {
性質1-1: 値1-1,
性質1-2: 値1-2,
...
},
プロパティ名2: {
性質2-1: 値2-1,
...
}
...
}
例:
// データアイテムを識別するためのID
id: { id: true }, //id:trueの意味については後述
// 名前
name: null,
// アドレス
address: null
}
スキーマのIDプロパティ指定
hifiveのデータモデルでは、データベースにおける主キー列のように、各データアイテムのいずれか1つのプロパティが各インスタンスを識別できる(異なる値を持つ)必要があります。
この指定を行うのが、スキーマ定義における「id: true」の指定です。
スキーマオブジェクトには、{id: true}が指定されているプロパティが必ず1つだけ必要です。
id:true指定したプロパティが、このデータモデルが持つデータアイテムを識別するためのIDプロパティとなります。
このプロパティの値は、必ずインスタンスごとに異なっていなければいけません。
その他の性質の記述
各プロパティには、性質を記述できます。nullを指定した場合は、一切の制約がないとみなされます。
詳細はリファレンス(仕様詳細) » ディスクリプタを参照してください。
type指定
プロパティに格納できる「型」を文字列で指定することができます。省略した場合はany(型制限無し)です。
型には「文字列」「製数値」「真偽値」などを指定できます。
参照:指定可能な型の一覧
typeが設定されているプロパティには、設定された型以外の値を代入することはできません。
型指定の例:
// 商品ID
id: {id:true},
// 商品名
name: {
type: 'string'
},
// 単価
unitPrice: {
type: 'integer'
},
// 数量
amount: {
type: 'integer'
}
};
型指定を行った場合の挙動例:
name: 'ProductModel',
schema: productSchema // 上で記述したスキーマオブジェクト
});
var item = model.create({
id: '001',
name: 'ボールペン',
unitPrice: 100,
amount: 5000
});
// 型指定と異なる値はsetできない
item.set('amount', 'abc'); // エラーになる
typeの配列指定
あるプロパティを、特定の型を要素とする配列であると宣言できます。
配列指定するには、"string[]", "any[]"のように、型名の後ろに「[]」を付け加えます。
typeで配列指定すると、当該プロパティ(下の例でのlistプロパティ)にはDataItemインスタンス生成時に自動的にObservableArrayインスタンスがセットされます。このインスタンスを変更することはできません。
DataItemのset()で配列をセットしようとすると、配列そのものではなく、中身がシャローコピーされます。
name: '',
schema: {
id: {
id: true
},
list: {
type: 'any[]'
}
}
};
var model = manager.createModel(descriptor);
var item = model.create({
id: '001'
});
var obsAry = item.get('list'); // [] 初期値は空ObservableArray
// 配列をset
var array = ['a', 'b', 'c'];
item.set('list', array);
item.get('list'); // ['a', 'b', 'c'] のObservableArray
item.get('list') !== array; // true, インスタンスは別
item.get('list') === obsAry; // true, 値を変更してもデータアイテムが持つObservableArrayインスタンスは変わらない
item.get('list').push('d');
item.get('list'); // ['a', 'b', 'c', 'd'] のObservableArray
depend
dependは同一データモデル内のプロパティに依存する値(計算値)を定義したいときに指定します。
depend指定されたプロパティには値をセットすることはできません(defaultValueも設定できません)。
depend指定では、「どのプロパティに依存するか」と「このプロパティの値を計算する関数」を指定します。
依存するプロパティの値が変更されると、自動的に関数が呼ばれ、このプロパティの値としてセットされます。
スキーマ記述と動作例:
// 商品ID
id: {id:true},
// 商品名
name: {
type: 'string'
},
// 単価
unitPrice: {
type: 'integer'
},
// 数量
amount: {
type: 'integer'
},
// 単価×数量
totalPrice: {
type: 'integer',
depend: {
on: ['unitPrice', 'amount'], // 同一データモデル内の、依存するプロパティを記述
calc: function(ev){
// onに指定されたいずれか1つ以上のプロパティが更新されたときにこの関数が実行されます。
// 引数(ev)はチェンジイベントオブジェクト
// thisはデータアイテムインスタンス
return this.get('unitPrice') * this.get('amount');
}
}
},
// メッセージ:"(商品)は(単価×数量)円分あります"
message: {
type: 'string',
depend: {
on: ['name', 'totalPrice'], // depend指定されている項目をさらに依存先に指定できる
calc: function(ev) {
return this.get('name') + 'は' + this.get('totalPrice') + '円分あります';
}
}
}
};
// データモデルの作成
var model = manager.createModel({
name: 'ProductModel',
schema: productSchema
});
// アイテムの作成
var item = model.create({
id: '001',
name: 'ノート'
});
item.set({
unitPrice: 120,
amount: 1000
});
item.get('totalPrice'); // 1200000
item.get('message'); // "ノートは120000円分あります"
次の章では、データアイテムの更新を監視する方法について説明します。
次のステップ ⇒ データアイテムの更新とイベント