データモデルの継承
ここでは、データモデルの継承について説明します。データモデル機構の基本的な説明はチュートリアル(データモデル編)をご覧ください。
データモデルのディスクリプタのbaseにデータモデル名を指定すると、スキーマに定義されたプロパティを継承することができます。
h5.core.data.createManager('TestManager', '');
// 継承元のデータモデルの作成
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true
},
name: {
type: 'string'
}
}
});
// ParentModelを継承するデータモデルの作成
TestManager.createModel({
name: 'ChildModel',
base: '@ParentModel', // @+既存のデータモデル名で、継承するデータモデルを指定する
schema: {
addr: {
type: 'string'
},
mail: {
type: 'string'
}
}
});
ChildModelは、baseに指定されたParentModelが持つプロパティを引き継ぎ、
- id (ID属性)
- name
- addr
- mail
のプロパティを持ちます。
さらに、このChildModelを継承するモデルを作成することもできます。
name: 'GrandchildModel',
base: '@ChildModel',
schema: {
age: {
type: 'integer'
}
}
});
GrandchildModelは、ChildModelが持つプロパティに加えて、ageプロパティを持ちます。
依存プロパティとイベント
継承元で定義されたプロパティでも、変更があれば継承先のアイテム、モデルのイベントが発生します。
また、継承元で定義されたプロパティをdepend.onに指定することもできます。
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true
},
price: {
type: 'integer'
}
}
});
// ParentModelを継承するデータモデルの作成
TestManager.createModel({
name: 'ChildModel',
base: '@ParentModel',
schema: {
itemName: {
type: 'string'
},
priceTaxIncl: {
depend: {
on: 'price', // 継承元のプロパティに依存
calc: function(ev) {
return this.get('price') * 1.05;
}
}
}
}).addEventListener('itemsChange', listener); // イベントハンドリング
// itemの生成。itemsChangeイベントが発火する
var item = manager.models.ChildModel.create({
id: '001',
price: 100,
itemName: '商品A'
});
// イベントハンドリング
item.addEventListener('change', itemListener);
// item.priceの変更。
item.set('price', 200);
// データアイテムのchangeイベント、データモデルのitemsChangeイベントが発火する。
// item.priceTaxInclの値が更新される (item.priceTaxIncl === 210)
プロパティが重複した場合
継承元と、継承先でプロパティ名が重複した場合は、継承先での定義で上書きます。
// 継承元のデータモデルの作成
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true
},
val: {
type: 'string'
}
}
});
// ParentModelを継承するデータモデルの作成
TestManager.createModel({
name: 'ChildModel',
base: '@ParentModel',
schema: {
// ParentModelのvalプロパティの定義を上書く
val: {
type: 'integer'
}
}
});
上記の例では、ParentModelのvalは文字列型ですが、ChildModelのvalは整数型になります。
ID属性
継承元で、ID属性のプロパティを定義した時、継承先と合わせてID指定された属性が2つ以上ある場合はエラーになります。
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true
},
val: {
type: 'string'
}
}
});
try{
// 継承先のデータモデルの作成
TestManager.createModel({
name: 'ChildModel',
base: '@ParentModel',
schema: {
childId: {
id: true
},
childVal: {
type: 'string'
}
}
});
} catch (e){
// ID指定されたプロパティがid, childIdの2つになってしまい、エラー
alert('error');
}
ID指定されたプロパティの定義を上書くことは可能です。
ただし、それがシステム上不整合にならないよう注意してください。
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true,
type: 'string'
},
val: {
type: 'string'
}
}
});
// 継承先のデータモデルの作成
TestManager.createModel({
name: 'ParentModel',
schema: {
id: {
id: true,
type: 'integer' // idのtypeをintegerに上書き
},
childVal: {
type: 'string'
}
}
});