Note that there are some explanatory texts on larger screens.

plurals
  1. POExtJS 4: Models with Associations and Stores
    primarykey
    data
    text
    <h1>Introduction</h1> <p>I'm facing an application design problem with the <code>Ext.data.Model</code> 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! </p> <h1>Models</h1> <p>Let's suppose you want to map the fact that "<em>Every customer can order multiple products</em>" to ExtJS. From the bare words one can identify these three models involved: <code>Customer</code>, <code>Order</code>, and <code>Product</code>. The <code>Order</code> in this case is what connects <code>Customer</code>s and <code>Product</code>s.</p> <h1>Associations</h1> <p>I found that ExtJS actually allows you to specify this <code>(Customer)1-n(Order)1-n(Product)</code> relation using the <code>Ext.data.HasManyAssociation</code> and <code>Ext.data.BelongsToAssociation</code> classes. But is this what one wants? Would you want to that a <code>Product</code> always belongs to an <code>Order</code>? What if you want to have a list of <code>Product</code>s without any connection to <code>Order</code>s whatsoever?</p> <h1>Stores</h1> <p>This is where it get's more ExtJS specific. In ExtJS you have <code>Ext.data.Store</code>s to hold all your data. To me a natural way to organize my data is to have an <code>Ext.data.Store</code> for each of my models:</p> <ol> <li><code>CustomerStore</code></li> <li><code>OrderStore</code></li> <li><code>ProductStore</code></li> </ol> <p>Consider having a three <code>Ext.grid.Panel</code>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.</p> <p><strong>Does this sound natural to you? If not, please comment!</strong></p> <h1>Bringing it all together</h1> <p>So now we have three things that we need to bring together:</p> <ol> <li>Models and their</li> <li>Associations (<code>hasMany</code>, <code>belongsTo</code>) and the</li> <li>Data (<code>Store</code>s)</li> </ol> <p>Is it possible to define an association only from one side of a Model-Model relation? For instance, can I specify that an <code>Order</code> <code>hasMany</code> <code>Product</code>s but leave out that a <code>Product</code> <code>belongsTo</code> an <code>Order</code>? Because a <code>Product</code> can actually belong to more than one <code>Order</code>. Therefore I specify that the <code>Product</code> model <code>hasMany</code> <code>Order</code>s below.</p> <p>Here are the models in ExtJS:</p> <h2>Customer</h2> <pre class="lang-js prettyprint-override"><code>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 */ }); </code></pre> <h2>Order</h2> <pre class="lang-js prettyprint-override"><code>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 */ }); </code></pre> <h2>Product</h2> <pre class="lang-js prettyprint-override"><code>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' }); </code></pre> <p>And here are the stores:</p> <h2>CustomerStore</h2> <pre class="lang-js prettyprint-override"><code>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' } } }); </code></pre> <h2>OrderStore</h2> <pre class="lang-js prettyprint-override"><code>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' } } }); </code></pre> <h2>ProductStore</h2> <pre class="lang-js prettyprint-override"><code>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' } } }); </code></pre> <p>Here is an example (not by me) with companies and their products <a href="http://superdit.com/2011/05/23/extjs-load-grid-from-another-grid/" rel="noreferrer">http://superdit.com/2011/05/23/extjs-load-grid-from-another-grid/</a> . It uses two Models and two stores but there are no associations define.</p> <p>Thank you in advance</p> <p>-Konrad</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload