| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 | 
							- <!DOCTYPE html>
 
- <html>
 
- <head>
 
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-   <title>The source code</title>
 
-   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
 
-   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
 
-   <style type="text/css">
 
-     .highlight { display: block; background-color: #ddd; }
 
-   </style>
 
-   <script type="text/javascript">
 
-     function highlight() {
 
-       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 
-     }
 
-   </script>
 
- </head>
 
- <body onload="prettyPrint(); highlight();">
 
-   <pre class="prettyprint lang-js"><span id='Ext-data-association-HasMany'>/**
 
- </span> * @author Ed Spencer
 
-  * @class Ext.data.association.HasMany
 
-  * 
 
-  * <p>Represents a one-to-many relationship between two models. Usually created indirectly via a model definition:</p>
 
-  * 
 
- <pre><code>
 
- Ext.define('Product', {
 
-     extend: 'Ext.data.Model',
 
-     fields: [
 
-         {name: 'id',      type: 'int'},
 
-         {name: 'user_id', type: 'int'},
 
-         {name: 'name',    type: 'string'}
 
-     ]
 
- });
 
- Ext.define('User', {
 
-     extend: 'Ext.data.Model',
 
-     fields: [
 
-         {name: 'id',   type: 'int'},
 
-         {name: 'name', type: 'string'}
 
-     ],
 
-     // we can use the hasMany shortcut on the model to create a hasMany association
 
-     hasMany: {model: 'Product', name: 'products'}
 
- });
 
- </pre></code>
 
- * 
 
-  * <p>Above we created Product and User models, and linked them by saying that a User hasMany Products. This gives
 
-  * us a new function on every User instance, in this case the function is called 'products' because that is the name
 
-  * we specified in the association configuration above.</p>
 
-  * 
 
-  * <p>This new function returns a specialized {@link Ext.data.Store Store} which is automatically filtered to load
 
-  * only Products for the given model instance:</p>
 
-  * 
 
- <pre><code>
 
- //first, we load up a User with id of 1
 
- var user = Ext.create('User', {id: 1, name: 'Ed'});
 
- //the user.products function was created automatically by the association and returns a {@link Ext.data.Store Store}
 
- //the created store is automatically scoped to the set of Products for the User with id of 1
 
- var products = user.products();
 
- //we still have all of the usual Store functions, for example it's easy to add a Product for this User
 
- products.add({
 
-     name: 'Another Product'
 
- });
 
- //saves the changes to the store - this automatically sets the new Product's user_id to 1 before saving
 
- products.sync();
 
- </code></pre>
 
-  * 
 
-  * <p>The new Store is only instantiated the first time you call products() to conserve memory and processing time,
 
-  * though calling products() a second time returns the same store instance.</p>
 
-  * 
 
-  * <p><u>Custom filtering</u></p>
 
-  * 
 
-  * <p>The Store is automatically furnished with a filter - by default this filter tells the store to only return
 
-  * records where the associated model's foreign key matches the owner model's primary key. For example, if a User
 
-  * with ID = 100 hasMany Products, the filter loads only Products with user_id == 100.</p>
 
-  * 
 
-  * <p>Sometimes we want to filter by another field - for example in the case of a Twitter search application we may
 
-  * have models for Search and Tweet:</p>
 
-  * 
 
- <pre><code>
 
- Ext.define('Search', {
 
-     extend: 'Ext.data.Model',
 
-     fields: [
 
-         'id', 'query'
 
-     ],
 
-     hasMany: {
 
-         model: 'Tweet',
 
-         name : 'tweets',
 
-         filterProperty: 'query'
 
-     }
 
- });
 
- Ext.define('Tweet', {
 
-     extend: 'Ext.data.Model',
 
-     fields: [
 
-         'id', 'text', 'from_user'
 
-     ]
 
- });
 
- //returns a Store filtered by the filterProperty
 
- var store = new Search({query: 'Sencha Touch'}).tweets();
 
- </code></pre>
 
-  * 
 
-  * <p>The tweets association above is filtered by the query property by setting the {@link #filterProperty}, and is
 
-  * equivalent to this:</p>
 
-  * 
 
- <pre><code>
 
- var store = Ext.create('Ext.data.Store', {
 
-     model: 'Tweet',
 
-     filters: [
 
-         {
 
-             property: 'query',
 
-             value   : 'Sencha Touch'
 
-         }
 
-     ]
 
- });
 
- </code></pre>
 
-  */
 
- Ext.define('Ext.data.association.HasMany', {
 
-     extend: 'Ext.data.association.Association',
 
-     alternateClassName: 'Ext.data.HasManyAssociation',
 
-     requires: ['Ext.util.Inflector'],
 
-     alias: 'association.hasmany',
 
- <span id='Ext-data-association-HasMany-cfg-foreignKey'>    /**
 
- </span>     * @cfg {String} foreignKey The name of the foreign key on the associated model that links it to the owner
 
-      * model. Defaults to the lowercased name of the owner model plus "_id", e.g. an association with a where a
 
-      * model called Group hasMany Users would create 'group_id' as the foreign key. When the remote store is loaded,
 
-      * the store is automatically filtered so that only records with a matching foreign key are included in the 
 
-      * resulting child store. This can be overridden by specifying the {@link #filterProperty}.
 
-      * <pre><code>
 
- Ext.define('Group', {
 
-     extend: 'Ext.data.Model',
 
-     fields: ['id', 'name'],
 
-     hasMany: 'User'
 
- });
 
- Ext.define('User', {
 
-     extend: 'Ext.data.Model',
 
-     fields: ['id', 'name', 'group_id'], // refers to the id of the group that this user belongs to
 
-     belongsTo: 'Group'
 
- });
 
-      * </code></pre>
 
-      */
 
-     
 
- <span id='Ext-data-association-HasMany-cfg-name'>    /**
 
- </span>     * @cfg {String} name The name of the function to create on the owner model to retrieve the child store.
 
-      * If not specified, the pluralized name of the child model is used.
 
-      * <pre><code>
 
- // This will create a users() method on any Group model instance
 
- Ext.define('Group', {
 
-     extend: 'Ext.data.Model',
 
-     fields: ['id', 'name'],
 
-     hasMany: 'User'
 
- });
 
- var group = new Group();
 
- console.log(group.users());
 
- // The method to retrieve the users will now be getUserList
 
- Ext.define('Group', {
 
-     extend: 'Ext.data.Model',
 
-     fields: ['id', 'name'],
 
-     hasMany: {model: 'User', name: 'getUserList'}
 
- });
 
- var group = new Group();
 
- console.log(group.getUserList());
 
-      * </code></pre>
 
-      */
 
-     
 
- <span id='Ext-data-association-HasMany-cfg-storeConfig'>    /**
 
- </span>     * @cfg {Object} storeConfig Optional configuration object that will be passed to the generated Store. Defaults to 
 
-      * undefined.
 
-      */
 
-     
 
- <span id='Ext-data-association-HasMany-cfg-filterProperty'>    /**
 
- </span>     * @cfg {String} filterProperty Optionally overrides the default filter that is set up on the associated Store. If
 
-      * this is not set, a filter is automatically created which filters the association based on the configured 
 
-      * {@link #foreignKey}. See intro docs for more details. Defaults to undefined
 
-      */
 
-     
 
- <span id='Ext-data-association-HasMany-cfg-autoLoad'>    /**
 
- </span>     * @cfg {Boolean} autoLoad True to automatically load the related store from a remote source when instantiated.
 
-      * Defaults to <tt>false</tt>.
 
-      */
 
-     
 
- <span id='Ext-data-association-HasMany-cfg-type'>    /**
 
- </span>     * @cfg {String} type The type configuration can be used when creating associations using a configuration object.
 
-      * Use 'hasMany' to create a HasMany association
 
-      * <pre><code>
 
- associations: [{
 
-     type: 'hasMany',
 
-     model: 'User'
 
- }]
 
-      * </code></pre>
 
-      */
 
-     
 
-     constructor: function(config) {
 
-         var me = this,
 
-             ownerProto,
 
-             name;
 
-             
 
-         me.callParent(arguments);
 
-         
 
-         me.name = me.name || Ext.util.Inflector.pluralize(me.associatedName.toLowerCase());
 
-         
 
-         ownerProto = me.ownerModel.prototype;
 
-         name = me.name;
 
-         
 
-         Ext.applyIf(me, {
 
-             storeName : name + "Store",
 
-             foreignKey: me.ownerName.toLowerCase() + "_id"
 
-         });
 
-         
 
-         ownerProto[name] = me.createStore();
 
-     },
 
-     
 
- <span id='Ext-data-association-HasMany-method-createStore'>    /**
 
- </span>     * @private
 
-      * Creates a function that returns an Ext.data.Store which is configured to load a set of data filtered
 
-      * by the owner model's primary key - e.g. in a hasMany association where Group hasMany Users, this function
 
-      * returns a Store configured to return the filtered set of a single Group's Users.
 
-      * @return {Function} The store-generating function
 
-      */
 
-     createStore: function() {
 
-         var that            = this,
 
-             associatedModel = that.associatedModel,
 
-             storeName       = that.storeName,
 
-             foreignKey      = that.foreignKey,
 
-             primaryKey      = that.primaryKey,
 
-             filterProperty  = that.filterProperty,
 
-             autoLoad        = that.autoLoad,
 
-             storeConfig     = that.storeConfig || {};
 
-         
 
-         return function() {
 
-             var me = this,
 
-                 config, filter,
 
-                 modelDefaults = {};
 
-                 
 
-             if (me[storeName] === undefined) {
 
-                 if (filterProperty) {
 
-                     filter = {
 
-                         property  : filterProperty,
 
-                         value     : me.get(filterProperty),
 
-                         exactMatch: true
 
-                     };
 
-                 } else {
 
-                     filter = {
 
-                         property  : foreignKey,
 
-                         value     : me.get(primaryKey),
 
-                         exactMatch: true
 
-                     };
 
-                 }
 
-                 
 
-                 modelDefaults[foreignKey] = me.get(primaryKey);
 
-                 
 
-                 config = Ext.apply({}, storeConfig, {
 
-                     model        : associatedModel,
 
-                     filters      : [filter],
 
-                     remoteFilter : false,
 
-                     modelDefaults: modelDefaults
 
-                 });
 
-                 
 
-                 me[storeName] = Ext.data.AbstractStore.create(config);
 
-                 if (autoLoad) {
 
-                     me[storeName].load();
 
-                 }
 
-             }
 
-             
 
-             return me[storeName];
 
-         };
 
-     },
 
-     
 
- <span id='Ext-data-association-HasMany-method-read'>    /**
 
- </span>     * Read associated data
 
-      * @private
 
-      * @param {Ext.data.Model} record The record we're writing to
 
-      * @param {Ext.data.reader.Reader} reader The reader for the associated model
 
-      * @param {Object} associationData The raw associated data
 
-      */
 
-     read: function(record, reader, associationData){
 
-         var store = record[this.name](),
 
-             inverse,
 
-             items, iLen, i;
 
-     
 
-         store.add(reader.read(associationData).records);
 
-     
 
-         //now that we've added the related records to the hasMany association, set the inverse belongsTo
 
-         //association on each of them if it exists
 
-         inverse = this.associatedModel.prototype.associations.findBy(function(assoc){
 
-             return assoc.type === 'belongsTo' && assoc.associatedName === record.$className;
 
-         });
 
-     
 
-         //if the inverse association was found, set it now on each record we've just created
 
-         if (inverse) {
 
-             items = store.data.items;
 
-             iLen  = items.length;
 
-             for (i = 0; i < iLen; i++) {
 
-                 items[i][inverse.instanceName] = record;
 
-             }
 
-         }
 
-     }
 
- });</pre>
 
- </body>
 
- </html>
 
 
  |