Introduction
I'm facing an application design problem with the Ext.data.Model
class in ExtJS. I will try to develop my ideas to a very common online store scenario here, so you can follow me. I would really appreciate any comments on my thoughts and conclusions!
Models
Let's suppose you want to map the fact that "Every customer can order multiple products" to ExtJS. From the bare words one can identify these three models involved: Customer
, Order
, and Product
. The Order
in this case is what connects Customer
s and
Product
s.
Associations
I found that ExtJS actually allows you to specify this (Customer)1-n(Order)1-n(Product)
relation using the Ext.data.HasManyAssociation
and Ext.data.BelongsToAssociation
classes. But is this what one wants? Would you want to that a Product
always belongs to an Order
? What if you want to have a list of Product
s without any connection to Order
s whatsoever?
Stores
This is where it get's more ExtJS specific. In ExtJS you have Ext.data.Store
s to hold all your data. To me a natural way to organize my data is to have an Ext.data.Store
for each of my models:
CustomerStore
OrderStore
ProductStore
Consider having a three Ext.grid.Panel
s side-by-side; one for each store. When selecting a customer in the one grid, his orders automatically show up in the second grid. When selecting an order in the second grid the associated products appear in the third grid.
Does this sound natural to you? If not, please comment!
Bringing it all together
So now we have three things that we need to bring together:
- Models and their
- Associations (
hasMany
,belongsTo
) and the - Data (
Store
s)
Is it possible to define an association only from one side of a Model-Model relation? For instance, can I specify that an Order
hasMany
Product
s but leave out that a Product
belongsTo
an Order
? Because a Product
can actually belong to more than one Order
. Therefore I specify that the Product
model hasMany
Order
s below.
Here are the models in ExtJS:
Customer
Ext.define('Customer', {
extend : 'Ext.data.Model',
requires : [
'Order',
],
fields : [
{name : 'id', type : 'int'},
{name : 'lastname', type : 'string'}
{name : 'firstname', type : 'string'}
],
hasMany: 'Order' /* Generates a orders() method on every Customer instance */
});
Order
Ext.define('Order', {
extend : 'Ext.data.Model',
fields : [
{name : 'id', type : 'int'},
{name : 'customer_id', type : 'int'}, /* refers to the customer that this order belongs to*/
{name : 'date', type : 'date'}
],
belongsTo: 'Customer', /* Generates a getCustomer method on every Order instance */
hasMany: 'Product' /* Generates a products() method on every Order instance */
});
Product
Ext.define('Product', {
extend : 'Ext.data.Model',
fields : [
{name : 'id', type : 'int'},
{name : 'name', type : 'string'},
{name : 'description', type : 'string'},
{name : 'price', type : 'float'}
],
/*
I don't specify the relation to the "Order" model here
because it simply doesn't belong here.
Will it still work?
*/
hasMany: 'Order'
});
And here are the stores:
CustomerStore
Ext.define('CustomerStore', {
extend : 'Ext.data.Store',
storeId : 'CustomerStore',
model : 'Customer',
proxy : {
type : 'ajax',
url : 'data/customers.json',
reader : {
type : 'json',
root : 'items',
totalProperty : 'total'
}
}
});
OrderStore
Ext.define('OrderStore', {
extend : 'Ext.data.Store',
storeId : 'OrderStore',
model : 'Order',
proxy : {
type : 'ajax',
url : 'data/orders.json',
reader : {
type : 'json',
root : 'items',
totalProperty : 'total'
}
}
});
ProductStore
Ext.define('ProductStore', {
extend : 'Ext.data.Store',
storeId : 'ProductStore',
model : 'Product',
proxy : {
type : 'ajax',
url : 'data/products.json',
reader : {
type : 'json',
root : 'items',
totalProperty : 'total'
}
}
});
Here is an example (not by me) with companies and their products http://superdit.com/2011/05/23/extjs-load-grid-from-another-grid/ . It uses two Models and two stores but there are no associations define.
Thank you in advance
-Konrad