extjs-mvc 0.4.0.j → 0.4.0.k
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 +1 -1
- data/VERSION +1 -1
- data/lib/extjs-mvc.rb +0 -14
- data/lib/extjs-mvc/api.rb +14 -27
- data/lib/extjs-mvc/src/App.js +219 -0
- data/lib/extjs-mvc/src/MVC.js +260 -0
- data/lib/extjs-mvc/src/Presenter.js +52 -0
- data/lib/extjs-mvc/src/README.rdoc +69 -0
- data/lib/extjs-mvc/src/controller/Controller.js +278 -0
- data/lib/extjs-mvc/src/controller/CrudController.js +460 -0
- data/lib/extjs-mvc/src/lib/Array.js +26 -0
- data/lib/extjs-mvc/src/lib/Booter.js +417 -0
- data/lib/extjs-mvc/src/lib/ClassManager.js +191 -0
- data/lib/extjs-mvc/src/lib/ControllerClassManager.js +95 -0
- data/lib/extjs-mvc/src/lib/Dependencies.js +44 -0
- data/lib/extjs-mvc/src/lib/DispatchMatcher.js +98 -0
- data/lib/extjs-mvc/src/lib/Dispatcher.js +129 -0
- data/lib/extjs-mvc/src/lib/Environment.js +43 -0
- data/lib/extjs-mvc/src/lib/Inflector.js +155 -0
- data/lib/extjs-mvc/src/lib/ModelClassManager.js +19 -0
- data/lib/extjs-mvc/src/lib/Route.js +139 -0
- data/lib/extjs-mvc/src/lib/Router.js +282 -0
- data/lib/extjs-mvc/src/lib/String.js +94 -0
- data/lib/extjs-mvc/src/lib/ViewClassManager.js +229 -0
- data/lib/extjs-mvc/src/lib/notes.txt +32 -0
- data/lib/extjs-mvc/src/model/AdapterManager.js +30 -0
- data/lib/extjs-mvc/src/model/Association.js +26 -0
- data/lib/extjs-mvc/src/model/Base.js +63 -0
- data/lib/extjs-mvc/src/model/BelongsToAssociation.js +116 -0
- data/lib/extjs-mvc/src/model/Cache.js +131 -0
- data/lib/extjs-mvc/src/model/HasManyAssociation.js +160 -0
- data/lib/extjs-mvc/src/model/Model.js +331 -0
- data/lib/extjs-mvc/src/model/UrlBuilder.js +106 -0
- data/lib/extjs-mvc/src/model/adapters/AbstractAdapter.js +296 -0
- data/lib/extjs-mvc/src/model/adapters/MemoryAdapter.js +103 -0
- data/lib/extjs-mvc/src/model/adapters/RESTAdapter.js +345 -0
- data/lib/extjs-mvc/src/model/adapters/RESTJSONAdapter.js +68 -0
- data/lib/extjs-mvc/src/model/adapters/notes.txt +42 -0
- data/lib/extjs-mvc/src/model/associations/Association.js +192 -0
- data/lib/extjs-mvc/src/model/associations/notes.txt +87 -0
- data/lib/extjs-mvc/src/model/validations/Errors.js +136 -0
- data/lib/extjs-mvc/src/model/validations/Plugin.js +139 -0
- data/lib/extjs-mvc/src/model/validations/Validations.js +276 -0
- data/lib/extjs-mvc/src/notes/Charts.graffle +0 -0
- data/lib/extjs-mvc/src/overrides/Ext.Component.js +21 -0
- data/lib/extjs-mvc/src/overrides/Ext.extend.js +142 -0
- data/lib/extjs-mvc/src/spec/Array.spec.js +15 -0
- data/lib/extjs-mvc/src/spec/ExtMVC.spec.js +65 -0
- data/lib/extjs-mvc/src/spec/Model.spec.js +370 -0
- data/lib/extjs-mvc/src/spec/OS.spec.js +83 -0
- data/lib/extjs-mvc/src/spec/Router.spec.js +99 -0
- data/lib/extjs-mvc/src/spec/SpecHelper.js +106 -0
- data/lib/extjs-mvc/src/spec/String.spec.js +83 -0
- data/lib/extjs-mvc/src/spec/model/AbstractAdapter.spec.js +49 -0
- data/lib/extjs-mvc/src/spec/model/Associations.spec.js +99 -0
- data/lib/extjs-mvc/src/spec/model/Cache.spec.js +5 -0
- data/lib/extjs-mvc/src/spec/model/RESTAdapter.spec.js +19 -0
- data/lib/extjs-mvc/src/spec/model/ValidationErrors.spec.js +64 -0
- data/lib/extjs-mvc/src/spec/model/Validations.spec.js +166 -0
- data/lib/extjs-mvc/src/spec/model/ValidationsPlugin.spec.js +108 -0
- data/lib/extjs-mvc/src/spec/suite.html +60 -0
- data/lib/extjs-mvc/src/specs-old/JSSpec.css +216 -0
- data/lib/extjs-mvc/src/specs-old/JSSpec.js +1512 -0
- data/lib/extjs-mvc/src/specs-old/all.html +66 -0
- data/lib/extjs-mvc/src/specs-old/base.js +14 -0
- data/lib/extjs-mvc/src/specs-old/controller.js +17 -0
- data/lib/extjs-mvc/src/specs-old/diff_match_patch.js +1 -0
- data/lib/extjs-mvc/src/specs-old/model.js +70 -0
- data/lib/extjs-mvc/src/specs-old/route.js +38 -0
- data/lib/extjs-mvc/src/specs-old/router.js +59 -0
- data/lib/extjs-mvc/src/specs-old/string.js +22 -0
- data/lib/extjs-mvc/src/testrunner/JSpecFormatter.js +111 -0
- data/lib/extjs-mvc/src/testrunner/TestClient.js +181 -0
- data/lib/extjs-mvc/src/testrunner/TestGrid.js +351 -0
- data/lib/extjs-mvc/src/testrunner/TestRunner.js +110 -0
- data/lib/extjs-mvc/src/testrunner/TestViewport.js +94 -0
- data/lib/extjs-mvc/src/vendor.yml +30 -0
- data/lib/extjs-mvc/src/vendor/ext-3.1.1/vendor.yml +16 -0
- data/lib/extjs-mvc/src/view/FormWindow.js +184 -0
- data/lib/extjs-mvc/src/view/HasManyEditorGridPanel.js +211 -0
- data/lib/extjs-mvc/src/view/scaffold/Edit.js +46 -0
- data/lib/extjs-mvc/src/view/scaffold/Index.js +561 -0
- data/lib/extjs-mvc/src/view/scaffold/New.js +20 -0
- data/lib/extjs-mvc/src/view/scaffold/ScaffoldFormPanel.js +255 -0
- data/lib/{vendor.yml → extjs-mvc/vendor.yml} +0 -0
- data/test/app/vendor/extjs-mvc/App.js +219 -0
- data/test/app/vendor/extjs-mvc/MVC.js +260 -0
- data/test/app/vendor/extjs-mvc/Presenter.js +52 -0
- data/test/app/vendor/extjs-mvc/README.rdoc +69 -0
- data/test/app/vendor/extjs-mvc/controller/Controller.js +278 -0
- data/test/app/vendor/extjs-mvc/controller/CrudController.js +460 -0
- data/test/app/vendor/extjs-mvc/lib/Array.js +26 -0
- data/test/app/vendor/extjs-mvc/lib/Booter.js +417 -0
- data/test/app/vendor/extjs-mvc/lib/ClassManager.js +191 -0
- data/test/app/vendor/extjs-mvc/lib/ControllerClassManager.js +95 -0
- data/test/app/vendor/extjs-mvc/lib/Dependencies.js +44 -0
- data/test/app/vendor/extjs-mvc/lib/DispatchMatcher.js +98 -0
- data/test/app/vendor/extjs-mvc/lib/Dispatcher.js +129 -0
- data/test/app/vendor/extjs-mvc/lib/Environment.js +43 -0
- data/test/app/vendor/extjs-mvc/lib/Inflector.js +155 -0
- data/test/app/vendor/extjs-mvc/lib/ModelClassManager.js +19 -0
- data/test/app/vendor/extjs-mvc/lib/Route.js +139 -0
- data/test/app/vendor/extjs-mvc/lib/Router.js +282 -0
- data/test/app/vendor/extjs-mvc/lib/String.js +94 -0
- data/test/app/vendor/extjs-mvc/lib/ViewClassManager.js +229 -0
- data/test/app/vendor/extjs-mvc/lib/notes.txt +32 -0
- data/test/app/vendor/extjs-mvc/model/AdapterManager.js +30 -0
- data/test/app/vendor/extjs-mvc/model/Association.js +26 -0
- data/test/app/vendor/extjs-mvc/model/Base.js +63 -0
- data/test/app/vendor/extjs-mvc/model/BelongsToAssociation.js +116 -0
- data/test/app/vendor/extjs-mvc/model/Cache.js +131 -0
- data/test/app/vendor/extjs-mvc/model/HasManyAssociation.js +160 -0
- data/test/app/vendor/extjs-mvc/model/Model.js +331 -0
- data/test/app/vendor/extjs-mvc/model/UrlBuilder.js +106 -0
- data/test/app/vendor/extjs-mvc/model/adapters/AbstractAdapter.js +296 -0
- data/test/app/vendor/extjs-mvc/model/adapters/MemoryAdapter.js +103 -0
- data/test/app/vendor/extjs-mvc/model/adapters/RESTAdapter.js +345 -0
- data/test/app/vendor/extjs-mvc/model/adapters/RESTJSONAdapter.js +68 -0
- data/test/app/vendor/extjs-mvc/model/adapters/notes.txt +42 -0
- data/test/app/vendor/extjs-mvc/model/associations/Association.js +192 -0
- data/test/app/vendor/extjs-mvc/model/associations/notes.txt +87 -0
- data/test/app/vendor/extjs-mvc/model/validations/Errors.js +136 -0
- data/test/app/vendor/extjs-mvc/model/validations/Plugin.js +139 -0
- data/test/app/vendor/extjs-mvc/model/validations/Validations.js +276 -0
- data/test/app/vendor/extjs-mvc/notes/Charts.graffle +0 -0
- data/test/app/vendor/extjs-mvc/overrides/Ext.Component.js +21 -0
- data/test/app/vendor/extjs-mvc/overrides/Ext.extend.js +142 -0
- data/test/app/vendor/extjs-mvc/spec/Array.spec.js +15 -0
- data/test/app/vendor/extjs-mvc/spec/ExtMVC.spec.js +65 -0
- data/test/app/vendor/extjs-mvc/spec/Model.spec.js +370 -0
- data/test/app/vendor/extjs-mvc/spec/OS.spec.js +83 -0
- data/test/app/vendor/extjs-mvc/spec/Router.spec.js +99 -0
- data/test/app/vendor/extjs-mvc/spec/SpecHelper.js +106 -0
- data/test/app/vendor/extjs-mvc/spec/String.spec.js +83 -0
- data/test/app/vendor/extjs-mvc/spec/model/AbstractAdapter.spec.js +49 -0
- data/test/app/vendor/extjs-mvc/spec/model/Associations.spec.js +99 -0
- data/test/app/vendor/extjs-mvc/spec/model/Cache.spec.js +5 -0
- data/test/app/vendor/extjs-mvc/spec/model/RESTAdapter.spec.js +19 -0
- data/test/app/vendor/extjs-mvc/spec/model/ValidationErrors.spec.js +64 -0
- data/test/app/vendor/extjs-mvc/spec/model/Validations.spec.js +166 -0
- data/test/app/vendor/extjs-mvc/spec/model/ValidationsPlugin.spec.js +108 -0
- data/test/app/vendor/extjs-mvc/spec/suite.html +60 -0
- data/test/app/vendor/extjs-mvc/specs-old/JSSpec.css +216 -0
- data/test/app/vendor/extjs-mvc/specs-old/JSSpec.js +1512 -0
- data/test/app/vendor/extjs-mvc/specs-old/all.html +66 -0
- data/test/app/vendor/extjs-mvc/specs-old/base.js +14 -0
- data/test/app/vendor/extjs-mvc/specs-old/controller.js +17 -0
- data/test/app/vendor/extjs-mvc/specs-old/diff_match_patch.js +1 -0
- data/test/app/vendor/extjs-mvc/specs-old/model.js +70 -0
- data/test/app/vendor/extjs-mvc/specs-old/route.js +38 -0
- data/test/app/vendor/extjs-mvc/specs-old/router.js +59 -0
- data/test/app/vendor/extjs-mvc/specs-old/string.js +22 -0
- data/test/app/vendor/extjs-mvc/testrunner/JSpecFormatter.js +111 -0
- data/test/app/vendor/extjs-mvc/testrunner/TestClient.js +181 -0
- data/test/app/vendor/extjs-mvc/testrunner/TestGrid.js +351 -0
- data/test/app/vendor/extjs-mvc/testrunner/TestRunner.js +110 -0
- data/test/app/vendor/extjs-mvc/testrunner/TestViewport.js +94 -0
- data/test/app/vendor/extjs-mvc/vendor.yml +30 -0
- data/test/app/vendor/extjs-mvc/vendor/ext-3.1.1/vendor.yml +16 -0
- data/test/app/vendor/extjs-mvc/view/FormWindow.js +184 -0
- data/test/app/vendor/extjs-mvc/view/HasManyEditorGridPanel.js +211 -0
- data/test/app/vendor/extjs-mvc/view/scaffold/Edit.js +46 -0
- data/test/app/vendor/extjs-mvc/view/scaffold/Index.js +561 -0
- data/test/app/vendor/extjs-mvc/view/scaffold/New.js +20 -0
- data/test/app/vendor/extjs-mvc/view/scaffold/ScaffoldFormPanel.js +255 -0
- data/test/helper.rb +7 -1
- data/test/test_extjs-mvc.rb +46 -0
- metadata +167 -7
- data/test/test_extjs-mvc-gem.rb +0 -7
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class ExtMVC
|
|
3
|
+
* ExtMVC
|
|
4
|
+
* @singleton
|
|
5
|
+
*/
|
|
6
|
+
ExtMVC = Ext.extend(Ext.util.Observable, {
|
|
7
|
+
version: "0.7a",
|
|
8
|
+
|
|
9
|
+
constructor: function() {
|
|
10
|
+
ExtMVC.superclass.constructor.apply(this, arguments);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @property dispatcher
|
|
14
|
+
* @type Ext.lib.Dispatcher
|
|
15
|
+
* The dispatcher object which finds the right controller and action when ExtMVC.dispatch is called
|
|
16
|
+
*/
|
|
17
|
+
// this.dispatcher = new Ext.lib.Dispatcher({
|
|
18
|
+
//
|
|
19
|
+
// });
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
dispatch: function() {
|
|
23
|
+
var dispatcher = this.dispatcher;
|
|
24
|
+
|
|
25
|
+
return dispatcher.dispatch.apply(dispatcher, arguments);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Sets the Ext.Application instance currently in use. This is currently required :/
|
|
30
|
+
* @param {Ext.Application} app The application currently in use
|
|
31
|
+
*/
|
|
32
|
+
setApplication: function(app) {
|
|
33
|
+
this.app = app;
|
|
34
|
+
this.name = app.name;
|
|
35
|
+
|
|
36
|
+
ExtMVC.model.modelNamespace = window[app.name].models;
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
fields: {
|
|
40
|
+
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
registerFields: function(name, fields) {
|
|
44
|
+
this.fields[name] = fields;
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
getFields: function(name) {
|
|
48
|
+
return this.fields[name];
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Registers a model class with Ext MVC
|
|
55
|
+
* @param {String} name The name to give this model
|
|
56
|
+
* @param {Object} config Model definition configuration
|
|
57
|
+
*/
|
|
58
|
+
registerModel: function(name, config) {
|
|
59
|
+
this.registerClass('model', arguments);
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Registers a controller class with Ext MVC
|
|
64
|
+
* @param {String} name The name to give this controller
|
|
65
|
+
* @param {Object} config Controller definition configuration
|
|
66
|
+
*/
|
|
67
|
+
registerController: function(name, config) {
|
|
68
|
+
this.registerClass('controller', arguments);
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Registers a view class with Ext MVC.
|
|
73
|
+
* @param {String} namesapce The namespace to add this view to
|
|
74
|
+
* @param {String} name The name to give this view
|
|
75
|
+
* @param {Object} config View definition configuration
|
|
76
|
+
*/
|
|
77
|
+
registerView: function(namespace, name, config) {
|
|
78
|
+
this.registerClass('view', arguments);
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Abstraction for registering views, models and controllers
|
|
83
|
+
* @param {String} managerName The name of the class manager to register with
|
|
84
|
+
* @param {Array} args The args to pass to the manager's register method
|
|
85
|
+
*/
|
|
86
|
+
registerClass: function(managerName, args) {
|
|
87
|
+
var manager = this.getClassManager(managerName);
|
|
88
|
+
|
|
89
|
+
manager.register.apply(manager, args);
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @property classManagers
|
|
94
|
+
* @type Object
|
|
95
|
+
* {name: classManager} mappings used by this.getClassManager and this.registerClassManager
|
|
96
|
+
*/
|
|
97
|
+
classManagers: {},
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @private
|
|
101
|
+
* Sets up model, view and controller class managers
|
|
102
|
+
*/
|
|
103
|
+
initializeClassManagers: function() {
|
|
104
|
+
this.registerClassManager('model', new ExtMVC.lib.ModelClassManager());
|
|
105
|
+
this.registerClassManager('view', new ExtMVC.lib.ViewClassManager());
|
|
106
|
+
this.registerClassManager('controller', new ExtMVC.lib.ControllerClassManager());
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Returns the class manager for the given name
|
|
111
|
+
* @param {String} name The name of the manager (model, view or controller)
|
|
112
|
+
* @return {ExtMVC.lib.ClassManager} The class manager instance
|
|
113
|
+
*/
|
|
114
|
+
getClassManager: function(name) {
|
|
115
|
+
return this.classManagers[name];
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Registers a class manager instance under a given name
|
|
120
|
+
* @param {String} name The name of the class manager
|
|
121
|
+
* @param {ExtMVC.lib.ClassManager} manager The ClassManager instance to register
|
|
122
|
+
*/
|
|
123
|
+
registerClassManager: function(name, manager) {
|
|
124
|
+
this.classManagers[name] = manager;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Returns the canonical controller instance for the given controller name
|
|
129
|
+
* @return {ExtMVC.Controller} The controller instance
|
|
130
|
+
*/
|
|
131
|
+
getController: function(name) {
|
|
132
|
+
return this.getClassManager('controller').getInstance(name);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Returns the constructor for a given model name
|
|
137
|
+
* @param {String} name The name of the model
|
|
138
|
+
* @return {Function} The model constructor
|
|
139
|
+
*/
|
|
140
|
+
getModel: function(name) {
|
|
141
|
+
return this.getClassManager('model').getConstructor(name);
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Instantiates a model of the given name with the data supplied
|
|
146
|
+
* @param {String} modelName The name of the model to instantiate
|
|
147
|
+
* @param {Object} data Data object to instantiate the instance with
|
|
148
|
+
* @return {ExtMVC.Model} The new model instance
|
|
149
|
+
*/
|
|
150
|
+
buildModel: function(modelName, data) {
|
|
151
|
+
return new (this.getModel(modelName))(data);
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Returns the constructor for a given view namespace/name combination
|
|
156
|
+
* @param {String} namespace The view namespace to look in
|
|
157
|
+
* @param {String} name The name of the view within the view namespace
|
|
158
|
+
* @return {Function} The view constructor
|
|
159
|
+
*/
|
|
160
|
+
getView: function getView(namespace, name) {
|
|
161
|
+
return this.getClassManager('view').getConstructor(namespace, name);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Returns a new view instance for the given namespace/name combo, using the supplied config
|
|
166
|
+
* @param {String} namespace The namespace to find the view from
|
|
167
|
+
* @param {String} name The view name
|
|
168
|
+
* @param {Object} config Optional config object
|
|
169
|
+
* @return {Ext.Component} The new view instance
|
|
170
|
+
*/
|
|
171
|
+
buildView: function buildView(namespace, name, config) {
|
|
172
|
+
var constructor = this.getView(namespace, name);
|
|
173
|
+
|
|
174
|
+
return new (constructor)(config);
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Loads packaged classes from a given url, calling a callback when they have been registered. Sample return:
|
|
179
|
+
<pre>
|
|
180
|
+
{
|
|
181
|
+
controllers: [
|
|
182
|
+
{
|
|
183
|
+
name: 'comments',
|
|
184
|
+
superclass: 'crud',
|
|
185
|
+
config: {
|
|
186
|
+
index: function() {
|
|
187
|
+
this.render('index', {
|
|
188
|
+
title: "Loaded on demand!"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
views: [
|
|
195
|
+
{
|
|
196
|
+
name: 'new',
|
|
197
|
+
namespace: 'comments',
|
|
198
|
+
config: {
|
|
199
|
+
xtype: 'scaffoldnew',
|
|
200
|
+
title: "New Comment"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
],
|
|
204
|
+
models: [
|
|
205
|
+
{
|
|
206
|
+
name : 'Comment',
|
|
207
|
+
config: {
|
|
208
|
+
fields: [
|
|
209
|
+
{name: 'id', type: 'int'},
|
|
210
|
+
{name: 'title', type: 'string'},
|
|
211
|
+
{name: 'message', type: 'string'}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
</pre>
|
|
218
|
+
* @param {String} url The url to retrieve the package from
|
|
219
|
+
* @param {Function} callback Optional callback function, called after the package has been read and registered
|
|
220
|
+
* @param {Object} scope The scope to execute the callback function in
|
|
221
|
+
*/
|
|
222
|
+
loadOnDemand: function(url, callback, scope) {
|
|
223
|
+
Ext.Ajax.request({
|
|
224
|
+
url : url,
|
|
225
|
+
scope : scope || this,
|
|
226
|
+
success: function(response) {
|
|
227
|
+
var pkg = Ext.decode(response.responseText);
|
|
228
|
+
|
|
229
|
+
Ext.each(pkg.controllers || [], function(config) {
|
|
230
|
+
this.registerController(config.name, config);
|
|
231
|
+
}, this);
|
|
232
|
+
|
|
233
|
+
Ext.each(pkg.models || [], function(config) {
|
|
234
|
+
this.registerModel(config.name, config);
|
|
235
|
+
}, this);
|
|
236
|
+
|
|
237
|
+
Ext.each(pkg.views || [], function(config) {
|
|
238
|
+
this.registerView(config.namespace, config.name, config);
|
|
239
|
+
}, this);
|
|
240
|
+
|
|
241
|
+
if (Ext.isFunction(callback)) callback.call(scope, pkg);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
ExtMVC = new ExtMVC();
|
|
248
|
+
|
|
249
|
+
// ExtMVC.initializeClassManagers();
|
|
250
|
+
|
|
251
|
+
Ext.onReady(function() {
|
|
252
|
+
/**
|
|
253
|
+
* @property dispatcher
|
|
254
|
+
* @type Ext.lib.Dispatcher
|
|
255
|
+
* The dispatcher object which finds the right controller and action when ExtMVC.dispatch is called
|
|
256
|
+
*/
|
|
257
|
+
ExtMVC.dispatcher = new ExtMVC.lib.Dispatcher();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
Ext.ns('ExtMVC.router', 'ExtMVC.plugin', 'ExtMVC.controller', 'ExtMVC.view', 'ExtMVC.view.scaffold', 'ExtMVC.lib', 'ExtMVC.test');
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class ExtMVC.Presenter
|
|
3
|
+
* @extends Ext.util.Observable
|
|
4
|
+
* Used as an interface between a controller and its views
|
|
5
|
+
*/
|
|
6
|
+
ExtMVC.Presenter = Ext.extend(Ext.util.Observable, {
|
|
7
|
+
|
|
8
|
+
constructor: function(config) {
|
|
9
|
+
ExtMVC.Presenter.superclass.constructor.apply(this, arguments);
|
|
10
|
+
|
|
11
|
+
this.addEvents(
|
|
12
|
+
/**
|
|
13
|
+
* @event load
|
|
14
|
+
* Fires when all items in the Presenter have been loaded
|
|
15
|
+
*/
|
|
16
|
+
'load'
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @property loaded
|
|
21
|
+
* @type Boolean
|
|
22
|
+
* True if all items that must be loaded before rendering have been
|
|
23
|
+
*/
|
|
24
|
+
this.loaded = false;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @property loading
|
|
28
|
+
* @type Boolean
|
|
29
|
+
* True while the loader is loading
|
|
30
|
+
*/
|
|
31
|
+
this.loading = false;
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
load: function() {
|
|
35
|
+
if (this.loaded || this.loading) return;
|
|
36
|
+
|
|
37
|
+
this.each(function(item, index, length) {
|
|
38
|
+
var callback = function(index) {
|
|
39
|
+
return function() {
|
|
40
|
+
if (index == length) {
|
|
41
|
+
this.loaded = true;
|
|
42
|
+
this.loading = false;
|
|
43
|
+
|
|
44
|
+
this.fireEvent('load');
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}(index);
|
|
48
|
+
|
|
49
|
+
item.on('load', callback, this, {single: true});
|
|
50
|
+
}, this);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
= Ext MVC
|
|
2
|
+
|
|
3
|
+
EXT MVC is a complete MVC stack on top of Ext JS (http://extjs.com).
|
|
4
|
+
|
|
5
|
+
== Base App
|
|
6
|
+
|
|
7
|
+
You are advised to use the base app to get up and running with Ext MVC as it sets everything up for you.
|
|
8
|
+
|
|
9
|
+
If you're comfortable with git:
|
|
10
|
+
|
|
11
|
+
1. git clone git://github.com/extmvc/baseapp.git myapp
|
|
12
|
+
2. cd myapp
|
|
13
|
+
3. rm -rf .git/
|
|
14
|
+
4. git init
|
|
15
|
+
|
|
16
|
+
If not:
|
|
17
|
+
|
|
18
|
+
1. Download the latest zip file from Github at http://github.com/extmvc/baseapp/zipball/master and unzip.
|
|
19
|
+
|
|
20
|
+
== Getting started
|
|
21
|
+
|
|
22
|
+
Read the readme file inside the base app and refer to http://extmvc.com
|
|
23
|
+
|
|
24
|
+
== Building
|
|
25
|
+
|
|
26
|
+
Ext MVC comes with a set of build tools for itself and your applications, written in Ruby. You need to be using
|
|
27
|
+
the Baseapp or a structure similar to it for these to work effectively.
|
|
28
|
+
|
|
29
|
+
=== Building your Ext MVC application
|
|
30
|
+
|
|
31
|
+
Build any app started from the base app by running this from the app's root directory:
|
|
32
|
+
|
|
33
|
+
ruby script/build all
|
|
34
|
+
|
|
35
|
+
This will examine the contents of index.html, pull out all of the javascript includes and concatenate them into
|
|
36
|
+
public/application-all.js. If you have the yui-compressor in your vendor directory (this is included by default)
|
|
37
|
+
and you have java installed, the build process will also minify your application-all.js into application-all-min.js.
|
|
38
|
+
|
|
39
|
+
Building your app also concatenates any CSS includes in index.html into public/application-all.css.
|
|
40
|
+
|
|
41
|
+
*NOTE*: Building looks at your index.html, NOT public/index.html. index.html is your development version,
|
|
42
|
+
public/index.html should simply include those concatenated/minified files.
|
|
43
|
+
|
|
44
|
+
=== Autobuild
|
|
45
|
+
|
|
46
|
+
If you need your app to be built every time you change any of the source files for whatever reason, use:
|
|
47
|
+
|
|
48
|
+
ruby script/build auto
|
|
49
|
+
|
|
50
|
+
This will again look at index.html and will force a rebuild any time any of those files are changed.
|
|
51
|
+
|
|
52
|
+
=== Other app build options
|
|
53
|
+
|
|
54
|
+
There are several other build commands, most of which are used by the two above:
|
|
55
|
+
|
|
56
|
+
- ruby script/build css - only build CSS files, no JS concatenation or minification
|
|
57
|
+
- ruby script/build js - only builds JS files, not CSS
|
|
58
|
+
- ruby script/build concatenate_js - concatenates but does not attempt to minify your JS
|
|
59
|
+
- ruby script/build minify_js - minifies an already concatenated public/application-all.js file
|
|
60
|
+
|
|
61
|
+
=== Building Ext MVC
|
|
62
|
+
|
|
63
|
+
If you are changing Ext MVC files and need to build Ext MVC itself, use:
|
|
64
|
+
|
|
65
|
+
- ruby script/build mvc
|
|
66
|
+
- ruby script/build mvc_auto
|
|
67
|
+
|
|
68
|
+
Again run from the app root directory. Like with ruby script/build auto, mvc_auto automatically rebuilds whenever
|
|
69
|
+
any Ext MVC file is changed.
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class ExtMVC.controller.Controller
|
|
3
|
+
* @extends Ext.util.Observable
|
|
4
|
+
* <h1>Controllers in Ext MVC</h1>
|
|
5
|
+
* <p>Controllers are the glue that stick applications together. They listen to events emitted by the UI as the user
|
|
6
|
+
* clicks interface elements, and take actions as appropriate. The relevant action may be to create or save a model
|
|
7
|
+
* instance, to render another view, to perform AJAX requests, or any other action.</p>
|
|
8
|
+
*
|
|
9
|
+
* <p>Controllers should be kept skinny as far as possible - receive an event, then hand any processing off to the
|
|
10
|
+
* appropriate model. This ensures we can keep the code as DRY as possible and makes refactoring easier.</p>
|
|
11
|
+
*
|
|
12
|
+
* <h2>Example Controller</h2>
|
|
13
|
+
* Here is a simple example controller which renders a couple of views and listens to events:
|
|
14
|
+
<pre><code>
|
|
15
|
+
//simple controller which manages the Page model within our application
|
|
16
|
+
MyApp.controllers.PagesController = Ext.extend(ExtMVC.controller.Controller, {
|
|
17
|
+
name: 'pages',
|
|
18
|
+
|
|
19
|
+
//renders the 'Index' template and sets up listeners
|
|
20
|
+
index: function() {
|
|
21
|
+
this.render('Index', {
|
|
22
|
+
listeners: {
|
|
23
|
+
scope : this,
|
|
24
|
+
'edit' : this.edit,
|
|
25
|
+
'delete': this.destroy
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
//renders the 'Edit' template (let's say it's a FormPanel), and loads the instance
|
|
31
|
+
edit: function(instance) {
|
|
32
|
+
this.render('Edit', {
|
|
33
|
+
listeners: {
|
|
34
|
+
scope : this,
|
|
35
|
+
save : this.update,
|
|
36
|
+
cancel : function() {
|
|
37
|
+
alert("You cancelled the update!");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}).loadRecord(instance);
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
//when the 'delete' event is fired by our 'Index' template (see the index action), this method is called.
|
|
44
|
+
//In this fictional example, we assume that the templates 'delete' event was called with the single argument
|
|
45
|
+
//of the Page instance the user wishes to destroy
|
|
46
|
+
destroy: function(instance) {
|
|
47
|
+
instance.destroy({
|
|
48
|
+
success: function() {
|
|
49
|
+
alert("The Page was deleted");
|
|
50
|
+
//at this point we might render another page for the user to look at
|
|
51
|
+
},
|
|
52
|
+
failure: function() {
|
|
53
|
+
alert('Curses! The Page could not be deleted');
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
//when the 'save' event is fired by our 'Edit' template, this method is called.
|
|
59
|
+
//Again, we assume that our template fired the event with the Page instance, and also an object with updates
|
|
60
|
+
update: function(instance, updates) {
|
|
61
|
+
//this applies the updates to the model instance and saves
|
|
62
|
+
instance.update(updates, {
|
|
63
|
+
success: function(updatedInstance) {
|
|
64
|
+
alert('Success! It saved');
|
|
65
|
+
//at this point we might render another page for the user to look at
|
|
66
|
+
},
|
|
67
|
+
failure: function(updatedInstance) {
|
|
68
|
+
alert('Darn it. Did not save');
|
|
69
|
+
|
|
70
|
+
//here we're firing the controller's update-failed event, which the view can pick up on
|
|
71
|
+
//The view can simply listen to our Pages controller and add errors from this instance to the form
|
|
72
|
+
//using form.markInvalid(instance.errors.forForm())
|
|
73
|
+
this.fireEvent('update-failed', instance);
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
//Sets up events emitted by this controller. Controllers are expected to fire events, so this method is called
|
|
79
|
+
//automatically when a controller is instantiated. Don't forget to call super here
|
|
80
|
+
initEvents: function() {
|
|
81
|
+
this.addEvents(
|
|
82
|
+
//this event will be fired when the controller can't update a Page instance
|
|
83
|
+
'update-failed'
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
MyApp.controllers.PagesController.superclass.initEvents.apply(this, arguments);
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
</code></pre>
|
|
90
|
+
* Note that many of the methods above are provided by the {@link ExtMVC.controller.CrudController CrudController}
|
|
91
|
+
*
|
|
92
|
+
* <h2>Rendering Views</h2>
|
|
93
|
+
* Each controller can automatically render view classes inside its views package. In the Pages controller above the
|
|
94
|
+
* views package is MyApp.views.pages - the application itself is called MyApp, and the 'pages' segment comes from the
|
|
95
|
+
* controller's 'name' property
|
|
96
|
+
* <br />
|
|
97
|
+
* <br />
|
|
98
|
+
* In the example above, the line: <pre><code>this.render('Edit', {})</code></pre> will automatically find the
|
|
99
|
+
* MyApp.views.pages.Edit class, with the second argument to this.render being a config argument passed to the view's constructor.
|
|
100
|
+
*
|
|
101
|
+
* <br />
|
|
102
|
+
* <h4>Rendering strategies</h4>
|
|
103
|
+
* Not all applications will render views in the same way
|
|
104
|
+
*/
|
|
105
|
+
// ExtMVC.controller.Controller = Ext.extend(Ext.util.Observable,
|
|
106
|
+
ExtMVC.registerController('controller', {
|
|
107
|
+
|
|
108
|
+
constructor: function(config) {
|
|
109
|
+
Ext.util.Observable.prototype.constructor.apply(this, arguments);
|
|
110
|
+
|
|
111
|
+
Ext.apply(this, {
|
|
112
|
+
/**
|
|
113
|
+
* @property renderStrategies
|
|
114
|
+
* @type Object
|
|
115
|
+
* An object of the form {xtype: function} which keys a container's xtype to the function to use
|
|
116
|
+
* when rendering a view to that container (see registerRenderStrategy)
|
|
117
|
+
*/
|
|
118
|
+
renderStrategies: {}
|
|
119
|
+
}, config || {});
|
|
120
|
+
|
|
121
|
+
this.registerDefaultRenderStrategies();
|
|
122
|
+
|
|
123
|
+
this.initEvents();
|
|
124
|
+
this.initListeners();
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Registers a rendering function for a given container xtype. When a view is rendered via this.render,
|
|
129
|
+
* the xtype of the container it is being rendered to is compared to the registered strategy xtypes, and
|
|
130
|
+
* the most specific match will be used to perform the rendering.
|
|
131
|
+
* @param {String} xtype The container xtype to register
|
|
132
|
+
* @param {Function} strategy The function to call when rendering to a container of the given xtype
|
|
133
|
+
*/
|
|
134
|
+
registerRenderStrategy: function(xtype, strategy) {
|
|
135
|
+
this.renderStrategies[xtype] = strategy;
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns the strategy function to use when rendering to the given container instance.
|
|
140
|
+
* @param {Ext.Container} container The container to add to
|
|
141
|
+
* @return {Function} The rendering strategy to use
|
|
142
|
+
*/
|
|
143
|
+
getRenderStrategy: function(container) {
|
|
144
|
+
var xtypes = container.getXTypes().split("/");
|
|
145
|
+
|
|
146
|
+
for (var i = xtypes.length - 1; i >= 0; i--){
|
|
147
|
+
var strategy = this.renderStrategies[xtypes[i]];
|
|
148
|
+
|
|
149
|
+
if (strategy != undefined) return strategy;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
throw new Ext.Error("No render strategy could be found for the container you specified");
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @private
|
|
157
|
+
* Adds the default strategies for panel and tabpanel
|
|
158
|
+
*/
|
|
159
|
+
registerDefaultRenderStrategies: function() {
|
|
160
|
+
this.registerRenderStrategy('panel', this.panelRenderStrategy);
|
|
161
|
+
this.registerRenderStrategy('tabpanel', this.tabPanelRenderStrategy);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Sets up events emitted by this controller. This defaults to an empty function and is
|
|
166
|
+
* called automatically when the controller is constructed so can simply be overridden
|
|
167
|
+
*/
|
|
168
|
+
initEvents: function() {},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Sets up events this controller listens to, and the actions the controller should take
|
|
172
|
+
* when each event is received. This defaults to an empty function and is called when
|
|
173
|
+
* the controller is constructed so can simply be overridden
|
|
174
|
+
*/
|
|
175
|
+
initListeners: function() {},
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Shows the user a notification message. Usually used to inform user of a successful save, deletion, etc
|
|
179
|
+
* This is an empty function which you must implement yourself
|
|
180
|
+
* @param {String} notice The string notice to display
|
|
181
|
+
*/
|
|
182
|
+
showNotice: function(notice) {},
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @property addTo
|
|
186
|
+
* @type Ext.Container
|
|
187
|
+
* The container to add views to using the 'add' renderMethod. Usually set to an Ext.TabPanel instance or similar
|
|
188
|
+
*/
|
|
189
|
+
addTo: null,
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Renders a given view name in the way set up by the controller. For this to work you must have passed a
|
|
193
|
+
* 'name' property when creating the controller, which is automatically used to find the view namespace for
|
|
194
|
+
* this controller. For example, in an application called MyApp, and a controller with a name of 'users',
|
|
195
|
+
* the view namespace would be MyApp.views.users, and render('Index') would search for a class called
|
|
196
|
+
* MyApp.views.users.Index and instantiate it with the passed config.
|
|
197
|
+
* An error is thrown if the view could not be found.
|
|
198
|
+
* @param {String} viewName The name of the view class within the view namespace used by this controller
|
|
199
|
+
* @param {Object} config Configuration options passed through to the view class' constructor
|
|
200
|
+
* @return {Ext.Component} The view object that was just created
|
|
201
|
+
*/
|
|
202
|
+
render: function render() {
|
|
203
|
+
//handle both method signatures
|
|
204
|
+
switch(arguments.length) {
|
|
205
|
+
case 1:
|
|
206
|
+
//this just falls through into case 2, which provides a config {} if one is not supplied
|
|
207
|
+
case 2:
|
|
208
|
+
var namespace = this.name,
|
|
209
|
+
viewName = arguments[0],
|
|
210
|
+
config = arguments[1] || {};
|
|
211
|
+
break;
|
|
212
|
+
case 3:
|
|
213
|
+
var namespace = arguments[0],
|
|
214
|
+
viewName = arguments[1],
|
|
215
|
+
config = arguments[2] || {};
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//we also use this constructor object to define whether or not the view should be added to the default
|
|
220
|
+
//container or not
|
|
221
|
+
Ext.applyIf(config, {
|
|
222
|
+
autoAdd: true,
|
|
223
|
+
addTo : ExtMVC.app.main
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
//NOTE: ExtMVC.getView will throw an error if the view hasn't been defined anywhere yet. At the moment this
|
|
227
|
+
//error will just propagate up as it's probably pretty clear, but we could provide a custom Error message here instead
|
|
228
|
+
var view = new (this.getView(namespace, viewName))(config);
|
|
229
|
+
|
|
230
|
+
if (config.autoAdd === true) {
|
|
231
|
+
if (view.isXType('window')) {
|
|
232
|
+
view.show();
|
|
233
|
+
} else {
|
|
234
|
+
this.getRenderStrategy(config.addTo)(config.addTo, view);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return view;
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Just calls ExtMVC.getView and returns. This is here because we override it in Crud Controller
|
|
243
|
+
* @param {String} namespace The view namespace
|
|
244
|
+
* @param {String} name The view name
|
|
245
|
+
* @return {Function} The view constructor function
|
|
246
|
+
*/
|
|
247
|
+
getView: function(namespace, name) {
|
|
248
|
+
return ExtMVC.getView(namespace, name);
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @private
|
|
253
|
+
* The tabpanel render strategy
|
|
254
|
+
*/
|
|
255
|
+
tabPanelRenderStrategy: function(container, view) {
|
|
256
|
+
var existing = container.getItem(view.id);
|
|
257
|
+
|
|
258
|
+
//don't add a tab with the same id as an existing one
|
|
259
|
+
if (existing == undefined) {
|
|
260
|
+
container.add(view);
|
|
261
|
+
container.doLayout();
|
|
262
|
+
container.activate(view);
|
|
263
|
+
} else {
|
|
264
|
+
container.setActiveTab(view.id);
|
|
265
|
+
view.destroy();
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* @private
|
|
271
|
+
* The panel render strategy
|
|
272
|
+
*/
|
|
273
|
+
panelRenderStrategy: function(container, view) {
|
|
274
|
+
container.removeAll();
|
|
275
|
+
container.add(view);
|
|
276
|
+
container.doLayout();
|
|
277
|
+
}
|
|
278
|
+
});
|