extjs-mvc 0.4.0.f → 0.4.0.g
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/bin/extjs-mvc +0 -3
- data/lib/extjs-mvc.rb +10 -6
- data/lib/extjs-mvc/api.rb +0 -1
- metadata +8 -84
- data/lib/src/App.js +0 -219
- data/lib/src/MVC.js +0 -260
- data/lib/src/Presenter.js +0 -52
- data/lib/src/README.rdoc +0 -69
- data/lib/src/controller/Controller.js +0 -278
- data/lib/src/controller/CrudController.js +0 -460
- data/lib/src/lib/Array.js +0 -26
- data/lib/src/lib/Booter.js +0 -416
- data/lib/src/lib/ClassManager.js +0 -191
- data/lib/src/lib/ControllerClassManager.js +0 -95
- data/lib/src/lib/Dependencies.js +0 -44
- data/lib/src/lib/DispatchMatcher.js +0 -98
- data/lib/src/lib/Dispatcher.js +0 -129
- data/lib/src/lib/Environment.js +0 -43
- data/lib/src/lib/Inflector.js +0 -155
- data/lib/src/lib/ModelClassManager.js +0 -19
- data/lib/src/lib/Route.js +0 -139
- data/lib/src/lib/Router.js +0 -282
- data/lib/src/lib/String.js +0 -94
- data/lib/src/lib/ViewClassManager.js +0 -229
- data/lib/src/lib/notes.txt +0 -32
- data/lib/src/model/AdapterManager.js +0 -30
- data/lib/src/model/Association.js +0 -26
- data/lib/src/model/Base.js +0 -63
- data/lib/src/model/BelongsToAssociation.js +0 -116
- data/lib/src/model/Cache.js +0 -131
- data/lib/src/model/HasManyAssociation.js +0 -160
- data/lib/src/model/Model.js +0 -331
- data/lib/src/model/UrlBuilder.js +0 -106
- data/lib/src/model/adapters/AbstractAdapter.js +0 -296
- data/lib/src/model/adapters/MemoryAdapter.js +0 -103
- data/lib/src/model/adapters/RESTAdapter.js +0 -345
- data/lib/src/model/adapters/RESTJSONAdapter.js +0 -68
- data/lib/src/model/adapters/notes.txt +0 -42
- data/lib/src/model/associations/Association.js +0 -192
- data/lib/src/model/associations/notes.txt +0 -87
- data/lib/src/model/validations/Errors.js +0 -136
- data/lib/src/model/validations/Plugin.js +0 -139
- data/lib/src/model/validations/Validations.js +0 -276
- data/lib/src/notes/Charts.graffle +0 -0
- data/lib/src/overrides/Ext.Component.js +0 -21
- data/lib/src/overrides/Ext.extend.js +0 -142
- data/lib/src/spec/Array.spec.js +0 -15
- data/lib/src/spec/ExtMVC.spec.js +0 -65
- data/lib/src/spec/Model.spec.js +0 -370
- data/lib/src/spec/OS.spec.js +0 -83
- data/lib/src/spec/Router.spec.js +0 -99
- data/lib/src/spec/SpecHelper.js +0 -106
- data/lib/src/spec/String.spec.js +0 -83
- data/lib/src/spec/model/AbstractAdapter.spec.js +0 -49
- data/lib/src/spec/model/Associations.spec.js +0 -99
- data/lib/src/spec/model/Cache.spec.js +0 -5
- data/lib/src/spec/model/RESTAdapter.spec.js +0 -19
- data/lib/src/spec/model/ValidationErrors.spec.js +0 -64
- data/lib/src/spec/model/Validations.spec.js +0 -166
- data/lib/src/spec/model/ValidationsPlugin.spec.js +0 -108
- data/lib/src/spec/suite.html +0 -60
- data/lib/src/specs-old/JSSpec.css +0 -216
- data/lib/src/specs-old/JSSpec.js +0 -1512
- data/lib/src/specs-old/all.html +0 -66
- data/lib/src/specs-old/base.js +0 -14
- data/lib/src/specs-old/controller.js +0 -17
- data/lib/src/specs-old/diff_match_patch.js +0 -1
- data/lib/src/specs-old/model.js +0 -70
- data/lib/src/specs-old/route.js +0 -38
- data/lib/src/specs-old/router.js +0 -59
- data/lib/src/specs-old/string.js +0 -22
- data/lib/src/testrunner/JSpecFormatter.js +0 -111
- data/lib/src/testrunner/TestClient.js +0 -181
- data/lib/src/testrunner/TestGrid.js +0 -351
- data/lib/src/testrunner/TestRunner.js +0 -110
- data/lib/src/testrunner/TestViewport.js +0 -94
- data/lib/src/vendor.yml +0 -29
- data/lib/src/vendor/ext-3.1.1/vendor.yml +0 -16
- data/lib/src/view/FormWindow.js +0 -184
- data/lib/src/view/HasManyEditorGridPanel.js +0 -211
- data/lib/src/view/scaffold/Edit.js +0 -46
- data/lib/src/view/scaffold/Index.js +0 -561
- data/lib/src/view/scaffold/New.js +0 -20
- data/lib/src/view/scaffold/ScaffoldFormPanel.js +0 -255
data/lib/src/model/Cache.js
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @class ExtMVC.model.Cache
|
3
|
-
* @extends Ext.util.Observable
|
4
|
-
* Provides an interface for caching model objects which have been fetched from some database/backend
|
5
|
-
*/
|
6
|
-
ExtMVC.model.Cache = function(config) {
|
7
|
-
var config = config || {};
|
8
|
-
|
9
|
-
ExtMVC.model.Cache.superclass.constructor.call(this, config);
|
10
|
-
|
11
|
-
this.addEvents(
|
12
|
-
/**
|
13
|
-
* @event beforeadd
|
14
|
-
* Fires before an item is added to the cache
|
15
|
-
* @param {ExtMVC.model} modelObject The model which is about to be added
|
16
|
-
*/
|
17
|
-
'beforeadd',
|
18
|
-
|
19
|
-
/**
|
20
|
-
* @event add
|
21
|
-
* Fires after an item is added to the cache
|
22
|
-
* @param {ExtMVC.model} modelObject The model which was just added
|
23
|
-
*/
|
24
|
-
'add',
|
25
|
-
|
26
|
-
/**
|
27
|
-
* @event beforeclear
|
28
|
-
* Fires before the cache is cleared
|
29
|
-
* @param {Number} seconds The number of seconds worth of caches which will be saved
|
30
|
-
*/
|
31
|
-
'beforeclear',
|
32
|
-
|
33
|
-
/**
|
34
|
-
* @event clear
|
35
|
-
* Fires after the cache has been cleared
|
36
|
-
* @param {Number} seconds The number of seconds worth of caches which were saved
|
37
|
-
*/
|
38
|
-
'clear'
|
39
|
-
);
|
40
|
-
};
|
41
|
-
|
42
|
-
Ext.extend(ExtMVC.model.Cache, Ext.util.Observable, {
|
43
|
-
|
44
|
-
/**
|
45
|
-
* @property caches
|
46
|
-
* @type Object
|
47
|
-
* Maintains all cached objects
|
48
|
-
*/
|
49
|
-
caches: {},
|
50
|
-
|
51
|
-
/**
|
52
|
-
* Adds the given model object to the cache. Automatically stores the datetime of the add
|
53
|
-
* @param {ExtMVC.model} modelObject The model you want to store in the cache
|
54
|
-
*/
|
55
|
-
add: function(modelObject) {
|
56
|
-
if (this.fireEvent('beforeadd', modelObject)) {
|
57
|
-
var modelName = modelObject.className;
|
58
|
-
var modelId = modelObject.data.id;
|
59
|
-
|
60
|
-
if (modelName && modelId) {
|
61
|
-
modelObject.cachedAt = new Date();
|
62
|
-
|
63
|
-
this.caches[modelName] = this.caches[modelName] || {};
|
64
|
-
this.caches[modelName][modelId] = modelObject;
|
65
|
-
|
66
|
-
this.fireEvent('add', modelObject);
|
67
|
-
return true;
|
68
|
-
} else {
|
69
|
-
|
70
|
-
return false;
|
71
|
-
};
|
72
|
-
}
|
73
|
-
},
|
74
|
-
|
75
|
-
/**
|
76
|
-
* Fetches an object from the cache
|
77
|
-
* @param {Object} params params object which must contain at least modelName and id. Optionally
|
78
|
-
* supply staleTime, which is the number of seconds old the cached object is allowed to be to get a hit,
|
79
|
-
* or a Date which will restrict hits to anything cached after that date
|
80
|
-
* @return {ExtMVC.model/null} The model if found, or null
|
81
|
-
*/
|
82
|
-
fetch: function(params) {
|
83
|
-
this.caches[params['modelName']] = this.caches[params['modelName']] || {};
|
84
|
-
|
85
|
-
var params = params || {};
|
86
|
-
var hit = this.caches[params['modelName']][params['id']];
|
87
|
-
|
88
|
-
if (hit) {
|
89
|
-
if (params.staleTime) {
|
90
|
-
if (typeof params.staleTime == 'number') {
|
91
|
-
var date = new Date();
|
92
|
-
date.setTime(date.getTime() - (1000 * params.staleTime));
|
93
|
-
params.staleTime = date;
|
94
|
-
};
|
95
|
-
|
96
|
-
//make sure we have a date object
|
97
|
-
if (params.staleTime.getTime && hit.cachedAt > params.staleTime) {
|
98
|
-
return hit;
|
99
|
-
}
|
100
|
-
} else {
|
101
|
-
return hit;
|
102
|
-
};
|
103
|
-
};
|
104
|
-
},
|
105
|
-
|
106
|
-
/**
|
107
|
-
* Clears all objects more than the given number of seconds old (defaults to clearing all objects)
|
108
|
-
* @param {Number} seconds The number of seconds to keep cached objects for (e.g. setting this to 10 would delete anything cached more than 10 seconds ago)
|
109
|
-
*/
|
110
|
-
clear: function(seconds) {
|
111
|
-
var seconds = seconds || 0;
|
112
|
-
var date = new Date();
|
113
|
-
date.setTime(date.getTime() - (1000 * seconds));
|
114
|
-
|
115
|
-
if (this.fireEvent('beforeclear', seconds)) {
|
116
|
-
if (seconds == 0) {
|
117
|
-
this.caches = {};
|
118
|
-
} else {
|
119
|
-
for (var i=0; i < this.caches.length; i++) {
|
120
|
-
for (var j=0; j < this.caches[i].length; j++) {
|
121
|
-
if (this.caches[i][j].cachedAt < date) {
|
122
|
-
delete this.caches[i][j];
|
123
|
-
};
|
124
|
-
};
|
125
|
-
};
|
126
|
-
};
|
127
|
-
|
128
|
-
this.fireEvent('clear', seconds);
|
129
|
-
}
|
130
|
-
}
|
131
|
-
});
|
@@ -1,160 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @class ExtMVC.model.HasManyAssociation
|
3
|
-
* @extends ExtMVC.model.Association
|
4
|
-
*/
|
5
|
-
ExtMVC.model.HasManyAssociation = function(ownerObject, config) {
|
6
|
-
var config = config || {};
|
7
|
-
|
8
|
-
Ext.applyIf(config, {
|
9
|
-
offset: 0,
|
10
|
-
limit: 25,
|
11
|
-
associationName: ExtMVC.model.Association.hasManyAssociationName(config.name)
|
12
|
-
});
|
13
|
-
|
14
|
-
//TODO: these should be abstracted to a parent object (as should private vars and funcs below)
|
15
|
-
Ext.applyIf(config, {
|
16
|
-
primaryKey: 'id',
|
17
|
-
foreignKey: ownerObject.foreignKeyName,
|
18
|
-
extend: {},
|
19
|
-
|
20
|
-
className: (ownerObject.constructor.namespace ? ownerObject.constructor.namespace + '.' + config.name : config.name)
|
21
|
-
});
|
22
|
-
|
23
|
-
//get a reference to the class definition function of the associated object
|
24
|
-
//(e.g. a hasMany: ['Post'] association will return a reference to Post)
|
25
|
-
var associatedObjectClass = eval(config.className);
|
26
|
-
|
27
|
-
/**
|
28
|
-
* Private, calls the ownerObject's class method with the supplied args
|
29
|
-
*/
|
30
|
-
function callOwnerObjectClassMethod(method, args, scope) {
|
31
|
-
return ownerObject.constructor[method].apply(scope || ownerObject.constructor, args || []);
|
32
|
-
};
|
33
|
-
|
34
|
-
/**
|
35
|
-
* Private, calls the associated object's class method with the supplied args
|
36
|
-
*/
|
37
|
-
function callAssociatedObjectClassMethod (method, args, scope) {
|
38
|
-
return associatedObjectClass[method].apply(scope || associatedObjectClass, args || []);
|
39
|
-
}
|
40
|
-
|
41
|
-
return Ext.applyIf(config.extend, {
|
42
|
-
|
43
|
-
/**
|
44
|
-
* @property associationName
|
45
|
-
* @type String
|
46
|
-
* Returns the name of this association so that the model can add it to its definition
|
47
|
-
*/
|
48
|
-
associationName: config.associationName,
|
49
|
-
|
50
|
-
/**
|
51
|
-
* @property associationType
|
52
|
-
* @type String
|
53
|
-
* The type of association (hasMany or belongsTo)
|
54
|
-
*/
|
55
|
-
associationType: 'hasMany',
|
56
|
-
|
57
|
-
/**
|
58
|
-
* Returns the URL for this association - e.g. if model User hasMany Posts, user.posts.url() will
|
59
|
-
* return something like /users/1/posts.
|
60
|
-
* Pass additional parameter options as arguments to pass straight through to the URL builder - e.g.:
|
61
|
-
* user.posts.url('published'); // = /users/1/posts/published
|
62
|
-
* @return {String} The URL for the has many resource
|
63
|
-
*/
|
64
|
-
url: function() {
|
65
|
-
var args = [ownerObject, associatedObjectClass];
|
66
|
-
for (var i=0; i < arguments.length; i++) {
|
67
|
-
args.push(arguments[i]);
|
68
|
-
};
|
69
|
-
|
70
|
-
return ExtMVC.UrlBuilder.urlFor.apply(ExtMVC.UrlBuilder, args);
|
71
|
-
},
|
72
|
-
|
73
|
-
/**
|
74
|
-
* Passes through to the owner class's findById class method, adding a foreign key constraint first
|
75
|
-
* @param {String} id The ID of the associated object to retrieve
|
76
|
-
* @param {Object} options Options passed along to the associated model's Class's findById method. Pass in loadSuccess, loadFailure, conditions, order etc here
|
77
|
-
*/
|
78
|
-
findById: function(id, options) {
|
79
|
-
var options = options || {};
|
80
|
-
|
81
|
-
//add a condition to constrain to the owner object's id
|
82
|
-
if (!options.conditions) { options.conditions = []; }
|
83
|
-
options.conditions.push({
|
84
|
-
key: config.foreignKey,
|
85
|
-
value: ownerObject.data[config.primaryKey]
|
86
|
-
});
|
87
|
-
|
88
|
-
return callAssociatedObjectClassMethod('findById', [id, options]);
|
89
|
-
},
|
90
|
-
|
91
|
-
findAll: function(storeOptions) {
|
92
|
-
var storeOptions = storeOptions || {};
|
93
|
-
Ext.applyIf(storeOptions, {
|
94
|
-
url: this.url(),
|
95
|
-
|
96
|
-
listeners: {
|
97
|
-
|
98
|
-
//Once we have fetched all hasMany records, make sure newRecord is false, and set the parent
|
99
|
-
//relationship to point to this ownerObject (The object which hasMany of these records)
|
100
|
-
'load': {
|
101
|
-
scope: this,
|
102
|
-
fn: function(store, records, options) {
|
103
|
-
Ext.each(records, function(record) {
|
104
|
-
record.newRecord = false;
|
105
|
-
if (record.parent && record.parent.set) {
|
106
|
-
record.parent.set(ownerObject);
|
107
|
-
}
|
108
|
-
}, this);
|
109
|
-
}
|
110
|
-
}
|
111
|
-
}
|
112
|
-
});
|
113
|
-
|
114
|
-
return callAssociatedObjectClassMethod('findAll', [storeOptions]);
|
115
|
-
},
|
116
|
-
|
117
|
-
/**
|
118
|
-
* Creates (builds and attempts to save) this associated model
|
119
|
-
* @param {Object} fields Object with keys and values to initialise this object
|
120
|
-
* @param {Object} saveConfig Passed to the Ext.Ajax request, supply success and failure options here
|
121
|
-
*/
|
122
|
-
create: function(fields, saveConfig) {
|
123
|
-
return this.build(fields).save(saveConfig);
|
124
|
-
},
|
125
|
-
|
126
|
-
/**
|
127
|
-
* Builds an instantiation of the associated model with the supplied data.
|
128
|
-
* Automatically links in the correct foreign key
|
129
|
-
* @param {Object} fields The data to initialize this object with
|
130
|
-
*/
|
131
|
-
build: function(fields) {
|
132
|
-
var fields = fields || {};
|
133
|
-
|
134
|
-
//instantiate the new object with the augmented fields
|
135
|
-
var obj = new associatedObjectClass(fields);
|
136
|
-
|
137
|
-
//set up the object's belongsTo association. This also sets up the foreign key
|
138
|
-
var assocName = ExtMVC.model.Association.belongsToAssociationName(ownerObject.className);
|
139
|
-
obj[assocName].set(ownerObject);
|
140
|
-
|
141
|
-
return obj;
|
142
|
-
},
|
143
|
-
|
144
|
-
/**
|
145
|
-
* Adds an existing (saved) instantiation of the associated model to this model's hasMany collection
|
146
|
-
* @param {ExtMVC.model} modelObject The existing, saved model
|
147
|
-
*/
|
148
|
-
add: function(modelObject) {
|
149
|
-
//TODO: implement this
|
150
|
-
|
151
|
-
},
|
152
|
-
|
153
|
-
destroy: function(id) {
|
154
|
-
//TODO: implement this
|
155
|
-
|
156
|
-
}
|
157
|
-
});
|
158
|
-
};
|
159
|
-
|
160
|
-
// Ext.extend(ExtMVC.model.HasManyAssociation, ExtMVC.model.Association);
|
data/lib/src/model/Model.js
DELETED
@@ -1,331 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @class ExtMVC.model
|
3
|
-
* @extends Object
|
4
|
-
* Manages the definition and creation of model classes.
|
5
|
-
*
|
6
|
-
* <h2>Defining models</h2>
|
7
|
-
* <p>Models in your application are defined using Ext.model.define, which is given 2 arguments - the String name of your model and a config object</p>
|
8
|
-
* <p>
|
9
|
-
* <pre><code>
|
10
|
-
ExtMVC.model.define("MyModel", {
|
11
|
-
fields: [
|
12
|
-
{name: 'id', type: 'int'},
|
13
|
-
{name: 'title', type: 'string'},
|
14
|
-
{name: 'price', type: 'int'}
|
15
|
-
],
|
16
|
-
|
17
|
-
validatesPresenceOf: ['id', 'title'],
|
18
|
-
classMethods: {
|
19
|
-
doSomething: function() {alert('oh hi!');}
|
20
|
-
}
|
21
|
-
});
|
22
|
-
</code></pre>
|
23
|
-
*
|
24
|
-
* Fields are passed straight to the underlying Ext.data.Record.
|
25
|
-
* classMethods are defined on the constructor function, e.g. from the example above:
|
26
|
-
*
|
27
|
-
<pre><code>
|
28
|
-
MyModel.doSomething(); //alerts 'oh hi'
|
29
|
-
</code></pre>
|
30
|
-
*
|
31
|
-
* All other properties are simply assigned to the Model's prototype, but may be intercepted by plugins
|
32
|
-
*
|
33
|
-
* <h2>Extending other models</h2>
|
34
|
-
* Models can extend other models using the 'extend' property:
|
35
|
-
<pre></code>
|
36
|
-
ExtMVC.model.define("Product", {
|
37
|
-
fields: [...]
|
38
|
-
}
|
39
|
-
|
40
|
-
ExtMVC.model.define("Flower", {
|
41
|
-
extend: "Product",
|
42
|
-
fields: [...]
|
43
|
-
}
|
44
|
-
</code></pre>
|
45
|
-
*
|
46
|
-
* The class builds a simple dependency graph to allow models to extend other models, e.g.:
|
47
|
-
*
|
48
|
-
<pre><code>
|
49
|
-
//this model definition will not actually be created until SuperUser has been defined
|
50
|
-
ExtMVC.model.define("SuperUser", {
|
51
|
-
extend: "User",
|
52
|
-
fields: [
|
53
|
-
{name: 'isAdmin', type: 'bool'}
|
54
|
-
]
|
55
|
-
});
|
56
|
-
|
57
|
-
//SuperUser does not extend anything, so is created immediately. User is then also created
|
58
|
-
ExtMVC.model.define("User", {
|
59
|
-
fields: [
|
60
|
-
{name: 'id', type: 'int'},
|
61
|
-
{name: 'username', type: 'string'}
|
62
|
-
],
|
63
|
-
|
64
|
-
validatesPresenceOf: ['id', 'username']
|
65
|
-
});
|
66
|
-
|
67
|
-
//At this point both SuperUser and User have been created and are instantiable and extendable.
|
68
|
-
</code></pre>
|
69
|
-
*
|
70
|
-
* When a model extends another one it inherits all of that model's instance and class methods. It also
|
71
|
-
* inherits all of the superclass model's fields, overwriting if redefined in the subclass. In the example
|
72
|
-
* above the SuperUser model would have fields 'id', 'username' and 'isAdmin', and will also have inherited
|
73
|
-
* User's validatesPresenceOf declaration
|
74
|
-
*
|
75
|
-
* @singleton
|
76
|
-
*/
|
77
|
-
ExtMVC.model = {
|
78
|
-
/**
|
79
|
-
* @property pendingCreation
|
80
|
-
* @type Object
|
81
|
-
* An object of model creation configurations awaiting definition because their dependency model(s) have not yet
|
82
|
-
* been defined. e.g. {'User': [{name: 'SuperUser', config: someConfigObject}, {name: 'AdminUser', config: anotherCfgObj}]}
|
83
|
-
* signifies that SuperUser and AdminUser should be defined as soon as User has been defined
|
84
|
-
*/
|
85
|
-
pendingCreation: {},
|
86
|
-
|
87
|
-
/**
|
88
|
-
* Returns an array of any Model subclasses waiting for this model to be defined
|
89
|
-
* @param {String} modelName The dependency model name to check against
|
90
|
-
* @return {Array} An array of model definitions (e.g. [{name: 'MyModel', config: someObject}])
|
91
|
-
*/
|
92
|
-
getModelsPendingDefinitionOf: function(modelName) {
|
93
|
-
return this.pendingCreation[modelName] || [];
|
94
|
-
},
|
95
|
-
|
96
|
-
/**
|
97
|
-
* Adds a model definition to the pendingCreation object if it is waiting for another model to be defined first
|
98
|
-
* @param {String} dependencyModelName The name of another model which must be created before this one
|
99
|
-
* @param {String} dependentModelName The name of the new model to be defined after its dependency
|
100
|
-
* @param {Object} config The new model's config object, as sent to ExtMVC.model.define
|
101
|
-
*/
|
102
|
-
setModelPendingDefinitionOf: function(dependencyModelName, dependentModelName, config) {
|
103
|
-
var arr = this.pendingCreation[dependencyModelName] || [];
|
104
|
-
|
105
|
-
arr.push({name: dependentModelName, config: config});
|
106
|
-
|
107
|
-
this.pendingCreation[dependencyModelName] = arr;
|
108
|
-
},
|
109
|
-
|
110
|
-
/**
|
111
|
-
* @property strictMode
|
112
|
-
* @type Boolean
|
113
|
-
* Throws errors rather than return false when performing operations such as overwriting existing models
|
114
|
-
* Defaults to false
|
115
|
-
*/
|
116
|
-
strictMode: false,
|
117
|
-
|
118
|
-
/**
|
119
|
-
* @property modelNamespace
|
120
|
-
* @type Object
|
121
|
-
* The object into which Models are defined. This defaults to window, meaning calls to ExtMVC.model.create
|
122
|
-
* will create models globally scoped unless this is modified. Setting this instead to MyApp.models would
|
123
|
-
* mean that a model called 'User' would be defined as MyApp.models.User instead
|
124
|
-
*/
|
125
|
-
modelNamespace: function() {
|
126
|
-
Ext.ns('ExtMVC.modelsTemp');
|
127
|
-
|
128
|
-
return ExtMVC.modelsTemp;
|
129
|
-
}(),
|
130
|
-
|
131
|
-
/**
|
132
|
-
* Sets a model up for creation. If this model doesn't extend any other Models that haven't been defined yet
|
133
|
-
* it is returned immediately, otherwise it is placed into a queue and defined as soon as its dependency models
|
134
|
-
* are in place. Example:
|
135
|
-
*
|
136
|
-
* ExtMVC.model.define('MyApp.models.MyModel', {
|
137
|
-
* fields: [
|
138
|
-
* {name: 'title', type: 'string'},
|
139
|
-
* {name: 'price', type: 'number'},
|
140
|
-
* {name: 'available', type: 'bool'}
|
141
|
-
* ],
|
142
|
-
*
|
143
|
-
* //Adds tax to the price field
|
144
|
-
* calculatePrice: function() {
|
145
|
-
* return this.data.price * 1.15;
|
146
|
-
* },
|
147
|
-
*
|
148
|
-
* classMethods: {
|
149
|
-
* findAvailable: function() {
|
150
|
-
* //some logic to find all available MyModel's
|
151
|
-
* }
|
152
|
-
* }
|
153
|
-
* });
|
154
|
-
*
|
155
|
-
* var m = new MyApp.models.MyModel({title: 'Test', available: true, price: 100});
|
156
|
-
* m.calculatePrice(); // => 115
|
157
|
-
* MyApp.models.MyModel.findAvailable(); // => Returns as defined above
|
158
|
-
*
|
159
|
-
* @param {String} modelName The name of the model to create (e.g. 'User')
|
160
|
-
* @param {Object} extensions An object containing field definitions and any extension methods to add to this model
|
161
|
-
* @return {ExtMVC.model.Base/Null} The newly defined model constructor, or null if the model can't be defined yet
|
162
|
-
*/
|
163
|
-
define: function(modelName, extensions) {
|
164
|
-
var createNow = true,
|
165
|
-
extensions = extensions || {};
|
166
|
-
|
167
|
-
if (typeof extensions.extend != 'undefined') {
|
168
|
-
var superclass = this.modelNamespace[extensions.extend];
|
169
|
-
if (typeof superclass == 'undefined') {
|
170
|
-
//the model we're extending hasn't been created yet
|
171
|
-
createNow = false;
|
172
|
-
this.setModelPendingDefinitionOf(extensions.extend, modelName, extensions);
|
173
|
-
};
|
174
|
-
};
|
175
|
-
|
176
|
-
if (createNow) return this.create.apply(this, arguments);
|
177
|
-
},
|
178
|
-
|
179
|
-
/**
|
180
|
-
* @ignore
|
181
|
-
* Creates a new ExtMVC.model.Base subclass and sets up all fields, instance and class methods.
|
182
|
-
* Don't use this directly unless you know what you're doing - use define instead (with the same arguments)
|
183
|
-
*
|
184
|
-
* @param {String} modelName The full model name to define, including namespace (e.g. 'MyApp.models.MyModel')
|
185
|
-
* @param {Object} extensions An object containing field definitions and any extension methods to add to this model
|
186
|
-
*/
|
187
|
-
create: function(modelName, extensions) {
|
188
|
-
extensions = extensions || {};
|
189
|
-
|
190
|
-
//check that this model has not already been defined
|
191
|
-
if (this.isAlreadyDefined(modelName)) {
|
192
|
-
if (this.strictMode) throw new Error(modelName + ' is already defined');
|
193
|
-
return false;
|
194
|
-
}
|
195
|
-
|
196
|
-
//get a handle on the super class model if extending (this will be undefined if we are not extending another model)
|
197
|
-
var superclassModel = this.modelNamespace[extensions.extend];
|
198
|
-
|
199
|
-
var fields = this.buildFields(extensions.fields, superclassModel);
|
200
|
-
delete extensions.fields;
|
201
|
-
|
202
|
-
//create the base Ext.data.Record, which we'll extend in a moment, and assign it to our model namespace
|
203
|
-
var model = this.modelNamespace[modelName] = Ext.data.Record.create(fields);
|
204
|
-
|
205
|
-
//separate out any methods meant to operate at class level
|
206
|
-
var classMethods = extensions.classMethods || {};
|
207
|
-
delete extensions.classMethods;
|
208
|
-
|
209
|
-
//extend our new record firstly with Model.Base, then apply any user extensions
|
210
|
-
Ext.apply(model.prototype, extensions);
|
211
|
-
|
212
|
-
//if we're extending another model, add class and instance methods now
|
213
|
-
if (typeof superclassModel != 'undefined') {
|
214
|
-
Ext.applyIf(classMethods, superclassModel);
|
215
|
-
Ext.applyIf(model.prototype, superclassModel.prototype);
|
216
|
-
};
|
217
|
-
|
218
|
-
//set up the various string names associated with this model
|
219
|
-
model.prototype.modelName = modelName;
|
220
|
-
this.setupNames(model);
|
221
|
-
|
222
|
-
//add any class methods to the class level
|
223
|
-
for (var methodName in classMethods) {
|
224
|
-
if (methodName != 'prototype') model[methodName] = classMethods[methodName];
|
225
|
-
};
|
226
|
-
|
227
|
-
this.initializePlugins(model);
|
228
|
-
this.afterCreate(modelName);
|
229
|
-
|
230
|
-
return model;
|
231
|
-
},
|
232
|
-
|
233
|
-
/**
|
234
|
-
* @ignore
|
235
|
-
* Creates any other models that were waiting for this one to be created. Do not override this
|
236
|
-
* unless you really know what you are doing...
|
237
|
-
* @param {String} modelName The name of the model that was just created
|
238
|
-
*/
|
239
|
-
afterCreate: function(modelName) {
|
240
|
-
var awaiting = this.getModelsPendingDefinitionOf(modelName);
|
241
|
-
if (awaiting) {
|
242
|
-
Ext.each(awaiting, function(obj) {
|
243
|
-
this.create(obj.name, obj.config);
|
244
|
-
}, this);
|
245
|
-
};
|
246
|
-
},
|
247
|
-
|
248
|
-
/**
|
249
|
-
* Checks if a given model name has already been defined, or is awaiting creation.
|
250
|
-
* @param {String} modelName the name of the new model to check
|
251
|
-
* @return {Boolean} True if the model has already been defined somewhere
|
252
|
-
*/
|
253
|
-
isAlreadyDefined: function(modelName) {
|
254
|
-
if (typeof this.modelNamespace[modelName] != "undefined") return true;
|
255
|
-
|
256
|
-
var found = false;
|
257
|
-
|
258
|
-
//check that this model is not awaiting creation
|
259
|
-
for (superclass in this.pendingCreation) {
|
260
|
-
var subclasses = this.pendingCreation[superclass];
|
261
|
-
Ext.each(subclasses, function(s) {
|
262
|
-
if (s.name == modelName) found = true;
|
263
|
-
}, this);
|
264
|
-
}
|
265
|
-
|
266
|
-
return found;
|
267
|
-
},
|
268
|
-
|
269
|
-
/**
|
270
|
-
* @ignore
|
271
|
-
* Builds an array of fields for this model, adding fields from the super class if present
|
272
|
-
*/
|
273
|
-
buildFields: function(subclassFields, superclass) {
|
274
|
-
subclassFields = subclassFields || [];
|
275
|
-
|
276
|
-
var fields = new Ext.util.MixedCollection(false, function(field) { return field.name; });
|
277
|
-
fields.addAll(subclassFields);
|
278
|
-
|
279
|
-
if (typeof superclass != 'undefined') {
|
280
|
-
superclass.prototype.fields.each(function(field) {
|
281
|
-
if (typeof fields.get(field.name) == 'undefined') fields.add(field);
|
282
|
-
});
|
283
|
-
};
|
284
|
-
|
285
|
-
return fields.items;
|
286
|
-
},
|
287
|
-
|
288
|
-
/**
|
289
|
-
* Sets up the various names required by this model, such as tableName, humanName etc
|
290
|
-
* @param {Object} model The model to set up names on
|
291
|
-
* @return {Object} The model, decorated with names
|
292
|
-
*/
|
293
|
-
setupNames: function(model) {
|
294
|
-
var p = model.prototype,
|
295
|
-
i = ExtMVC.Inflector;
|
296
|
-
|
297
|
-
Ext.applyIf(model.prototype, {
|
298
|
-
tableName : i.pluralize(p.modelName.underscore()),
|
299
|
-
foreignKeyName : i.singularize(p.modelName.underscore()) + '_id',
|
300
|
-
singularHumanName: p.modelName.humanize().titleize(),
|
301
|
-
pluralHumanName : i.pluralize(p.modelName.humanize().titleize())
|
302
|
-
});
|
303
|
-
},
|
304
|
-
|
305
|
-
/**
|
306
|
-
* @property plugins
|
307
|
-
* @type Array
|
308
|
-
* An array containing all plugin constructor functions - these get applied at model creation time
|
309
|
-
*/
|
310
|
-
plugins: [],
|
311
|
-
|
312
|
-
/**
|
313
|
-
* Makes Model aware of a new plugin. All plugins defined here will be initialized when a model is created
|
314
|
-
* @param {Function} plugin The plugin object
|
315
|
-
*/
|
316
|
-
addPlugin: function(plugin) {
|
317
|
-
this.plugins.push(plugin);
|
318
|
-
},
|
319
|
-
|
320
|
-
/**
|
321
|
-
* Runs each plugin's initialize method with a newly created model constructor
|
322
|
-
* @param {ExtMVC.model} model The model to initialize the plugin with
|
323
|
-
*/
|
324
|
-
initializePlugins: function(model) {
|
325
|
-
Ext.each(this.plugins, function(plugin) {
|
326
|
-
plugin.initialize(model);
|
327
|
-
}, this);
|
328
|
-
}
|
329
|
-
};
|
330
|
-
|
331
|
-
Ext.ns('ExtMVC.model.plugin');
|