Upgrade to ExtJS 4.0.7 - Released 10/19/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
24 Model instances can be created by using the {@link Ext#create Ext.create} method. Ext.create replaces
25 the deprecated {@link #create Ext.ModelManager.create} method. It is also possible to create a model instance
26 this by using the Model type directly. The following 3 snippets are equivalent:
27
28     Ext.define('User', {
29         extend: 'Ext.data.Model',
30         fields: ['first', 'last']
31     });
32
33     // method 1, create using Ext.create (recommended)
34     Ext.create('User', {
35         first: 'Ed',
36         last: 'Spencer'
37     });
38
39     // method 2, create through the manager (deprecated)
40     Ext.ModelManager.create({
41         first: 'Ed',
42         last: 'Spencer'
43     }, 'User');
44
45     // method 3, create on the type directly
46     new User({
47         first: 'Ed',
48         last: 'Spencer'
49     });
50
51 __Accessing Model Types__
52
53 A reference to a Model type can be obtained by using the {@link #getModel} function. Since models types
54 are normal classes, you can access the type directly. The following snippets are equivalent:
55
56     Ext.define('User', {
57         extend: 'Ext.data.Model',
58         fields: ['first', 'last']
59     });
60
61     // method 1, access model type through the manager
62     var UserType = Ext.ModelManager.getModel('User');
63
64     // method 2, reference the type directly
65     var UserType = User;
66
67  * @markdown
68  * @singleton
69  */
70 Ext.define('Ext.ModelManager', {
71     extend: 'Ext.AbstractManager',
72     alternateClassName: 'Ext.ModelMgr',
73     requires: ['Ext.data.Association'],
74
75     singleton: true,
76
77     typeName: 'mtype',
78
79     /**
80      * Private stack of associations that must be created once their associated model has been defined
81      * @property {Ext.data.Association[]} associationStack
82      */
83     associationStack: [],
84
85     /**
86      * Registers a model definition. All model plugins marked with isDefault: true are bootstrapped
87      * immediately, as are any addition plugins defined in the model config.
88      * @private
89      */
90     registerType: function(name, config) {
91         var proto = config.prototype,
92             model;
93         if (proto && proto.isModel) {
94             // registering an already defined model
95             model = config;
96         } else {
97             // passing in a configuration
98             if (!config.extend) {
99                 config.extend = 'Ext.data.Model';
100             }
101             model = Ext.define(name, config);
102         }
103         this.types[name] = model;
104         return model;
105     },
106
107     /**
108      * @private
109      * Private callback called whenever a model has just been defined. This sets up any associations
110      * that were waiting for the given model to be defined
111      * @param {Function} model The model that was just created
112      */
113     onModelDefined: function(model) {
114         var stack  = this.associationStack,
115             length = stack.length,
116             create = [],
117             association, i, created;
118
119         for (i = 0; i < length; i++) {
120             association = stack[i];
121
122             if (association.associatedModel == model.modelName) {
123                 create.push(association);
124             }
125         }
126
127         for (i = 0, length = create.length; i < length; i++) {
128             created = create[i];
129             this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created));
130             Ext.Array.remove(stack, created);
131         }
132     },
133
134     /**
135      * Registers an association where one of the models defined doesn't exist yet.
136      * The ModelManager will check when new models are registered if it can link them
137      * together
138      * @private
139      * @param {Ext.data.Association} association The association
140      */
141     registerDeferredAssociation: function(association){
142         this.associationStack.push(association);
143     },
144
145     /**
146      * Returns the {@link Ext.data.Model} for a given model name
147      * @param {String/Object} id The id of the model or the model instance.
148      * @return {Ext.data.Model} a model class.
149      */
150     getModel: function(id) {
151         var model = id;
152         if (typeof model == 'string') {
153             model = this.types[model];
154         }
155         return model;
156     },
157
158     /**
159      * Creates a new instance of a Model using the given data.
160      *
161      * This method is deprecated.  Use {@link Ext#create Ext.create} instead.  For example:
162      *
163      *     Ext.create('User', {
164      *         first: 'Ed',
165      *         last: 'Spencer'
166      *     });
167      *
168      * @param {Object} data Data to initialize the Model's fields with
169      * @param {String} name The name of the model to create
170      * @param {Number} id (Optional) unique id of the Model instance (see {@link Ext.data.Model})
171      */
172     create: function(config, name, id) {
173         var con = typeof name == 'function' ? name : this.types[name || config.name];
174
175         return new con(config, id);
176     }
177 }, function() {
178
179     /**
180      * Old way for creating Model classes.  Instead use:
181      *
182      *     Ext.define("MyModel", {
183      *         extend: "Ext.data.Model",
184      *         fields: []
185      *     });
186      *
187      * @param {String} name Name of the Model class.
188      * @param {Object} config A configuration object for the Model you wish to create.
189      * @return {Ext.data.Model} The newly registered Model
190      * @member Ext
191      * @deprecated 4.0.0 Use {@link Ext#define} instead.
192      */
193     Ext.regModel = function() {
194         //<debug>
195         if (Ext.isDefined(Ext.global.console)) {
196             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: []});.');
197         }
198         //</debug>
199         return this.ModelManager.registerType.apply(this.ModelManager, arguments);
200     };
201 });
202