Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / ModelManager.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @author Ed Spencer
17  * @class Ext.ModelManager
18  * @extends Ext.AbstractManager
19
20 The ModelManager keeps track of all {@link Ext.data.Model} types defined in your application.
21
22 __Creating Model Instances__
23 Model instances can be created by using the {@link #create} function. It is also possible to do
24 this by using the Model type directly. The following snippets are equivalent:
25
26     Ext.define('User', {
27         extend: 'Ext.data.Model',
28         fields: ['first', 'last']
29     });
30     
31     // method 1, create through the manager
32     Ext.ModelManager.create({
33         first: 'Ed',
34         last: 'Spencer'
35     }, 'User');
36     
37     // method 2, create on the type directly
38     new User({
39         first: 'Ed',
40         last: 'Spencer'
41     });
42     
43 __Accessing Model Types__
44 A reference to a Model type can be obtained by using the {@link #getModel} function. Since models types
45 are normal classes, you can access the type directly. The following snippets are equivalent:
46
47     Ext.define('User', {
48         extend: 'Ext.data.Model',
49         fields: ['first', 'last']
50     });
51     
52     // method 1, access model type through the manager
53     var UserType = Ext.ModelManager.getModel('User');
54     
55     // method 2, reference the type directly
56     var UserType = User;
57
58  * @markdown
59  * @singleton
60  */
61 Ext.define('Ext.ModelManager', {
62     extend: 'Ext.AbstractManager',
63     alternateClassName: 'Ext.ModelMgr',
64     requires: ['Ext.data.Association'],
65     
66     singleton: true,
67     
68     typeName: 'mtype',
69     
70     /**
71      * Private stack of associations that must be created once their associated model has been defined
72      * @property associationStack
73      * @type Array
74      */
75     associationStack: [],
76     
77     /**
78      * Registers a model definition. All model plugins marked with isDefault: true are bootstrapped
79      * immediately, as are any addition plugins defined in the model config.
80      * @private
81      */
82     registerType: function(name, config) {
83         var proto = config.prototype,
84             model;
85         if (proto && proto.isModel) {
86             // registering an already defined model
87             model = config;
88         } else {
89             // passing in a configuration
90             if (!config.extend) {
91                 config.extend = 'Ext.data.Model';
92             }
93             model = Ext.define(name, config);
94         }
95         this.types[name] = model;
96         return model;
97     },
98     
99     /**
100      * @private
101      * Private callback called whenever a model has just been defined. This sets up any associations
102      * that were waiting for the given model to be defined
103      * @param {Function} model The model that was just created
104      */
105     onModelDefined: function(model) {
106         var stack  = this.associationStack,
107             length = stack.length,
108             create = [],
109             association, i, created;
110         
111         for (i = 0; i < length; i++) {
112             association = stack[i];
113             
114             if (association.associatedModel == model.modelName) {
115                 create.push(association);
116             }
117         }
118         
119         for (i = 0, length = create.length; i < length; i++) {
120             created = create[i];
121             this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created));
122             Ext.Array.remove(stack, created);
123         }
124     },
125     
126     /**
127      * Registers an association where one of the models defined doesn't exist yet.
128      * The ModelManager will check when new models are registered if it can link them
129      * together
130      * @private
131      * @param {Ext.data.Association} association The association
132      */
133     registerDeferredAssociation: function(association){
134         this.associationStack.push(association);
135     },
136     
137     /**
138      * Returns the {@link Ext.data.Model} for a given model name
139      * @param {String/Object} id The id of the model or the model instance.
140      */
141     getModel: function(id) {
142         var model = id;
143         if (typeof model == 'string') {
144             model = this.types[model];
145         }
146         return model;
147     },
148     
149     /**
150      * Creates a new instance of a Model using the given data.
151      * @param {Object} data Data to initialize the Model's fields with
152      * @param {String} name The name of the model to create
153      * @param {Number} id Optional unique id of the Model instance (see {@link Ext.data.Model})
154      */
155     create: function(config, name, id) {
156         var con = typeof name == 'function' ? name : this.types[name || config.name];
157         
158         return new con(config, id);
159     }
160 }, function() {
161     
162     /**
163      * Creates a new Model class from the specified config object. See {@link Ext.data.Model} for full examples.
164      * 
165      * @param {Object} config A configuration object for the Model you wish to create.
166      * @return {Ext.data.Model} The newly registered Model
167      * @member Ext
168      * @method regModel
169      */
170     Ext.regModel = function() {
171         //<debug>
172         if (Ext.isDefined(Ext.global.console)) {
173             Ext.global.console.warn('Ext.regModel has been deprecated. Models can now be created by extending Ext.data.Model: Ext.define("MyModel", {extend: "Ext.data.Model", fields: []});.');
174         }
175         //</debug>
176         return this.ModelManager.registerType.apply(this.ModelManager, arguments);
177     };
178 });
179