PDA

View Full Version : Proxy as its own class, doesn't work with api property?



quaidbrown
9 Jan 2012, 2:46 PM
I wanted to break my proxy out into its own object.  How should I have done this to make it work? I'm still a little fuzzy on 'this' scoping and such.  Any tips for learning 'this'?



Doesn't work... can't resolve the URLs. Works if I specify the url: property, but dies when I try to break it down with the api: property.


Ext.define('AM.proxy.AppointmentAjaxRemoteProxy',{
extend: 'Ext.data.proxy.Ajax',
type: 'ajax',

api: {
create : '/SchedulingService/Appointment/SetAppointment/SetAppointment',
read : '/SchedulingService/Appointment/Appointments',
update : '/SchedulingService/Appointment/SetAppointment/SetAppointment',
destroy : '/SchedulingService/Appointment/SetAppointment/SetAppointment'
},
reader: {
type: 'json',
root: 'GetAppointmentsResult',
successProperty: 'success'
}
});







Ext.define('AM.store.AppointmentStore',{
extend: 'Ext.data.Store',
model: 'AM.model.AppointmentModel',
autoLoad: true,

proxy: Ext.create('AM.proxy.AppointmentAjaxRemoteProxy')

});


This works:


Ext.define('AM.store.AppointmentStore',{
extend: 'Ext.data.Store',
model: 'AM.model.AppointmentModel',
autoLoad: true,

proxy:{
type: 'ajax',
api: {
create : '/SchedulingService/Appointment/SetAppointment',
read : '/SchedulingService/Appointment/Appointments',
update : '/SchedulingService/Appointment/SetAppointment',
destroy : '/SchedulingService/Appointment/SetAppointment'
},
reader: {
type: 'json',
root: 'GetAppointmentsResult',
successProperty: 'success'
}
}
//Ext.create('AM.proxy.AppointmentAjaxRemoteProxy')

});

mitchellsimoens
10 Jan 2012, 7:12 AM
When you create your proxy class, you shouldn't use the type 'ajax' as that is already used by the ajax proxy.

I would suggest not to define your store like this:


Ext.define('AM.store.AppointmentStore',{
extend: 'Ext.data.Store',
model: 'AM.model.AppointmentModel',
autoLoad: true,

proxy: Ext.create('AM.proxy.AppointmentAjaxRemoteProxy')

});

If you have 2 or more instances of the AM.store.AppointmentStore store then all those instances will share the same proxy instance.

quaidbrown
10 Jan 2012, 7:47 AM
Thanks so much for the reply.


I
f you have 2 or more instances of the AM.store.AppointmentStore store then all those instances will share the same proxy instance.

Is
proxy:
Ext.create('AM.proxy.AppointmentAjaxRemoteProxy') behaving like a static property of my proxy? Why would it behave differently than the proxy:{} syntax?

I'm doing this because I'd like to come up with a way to easily swap remote proxies for local proxies reading/writing to files so I can do unit testing without having my services available.

mitchellsimoens
10 Jan 2012, 7:50 AM
A config object can be copied (hopefully it does on proxy) where as a class instance won't be

quaidbrown
10 Jan 2012, 8:27 AM
What do you mean by "can be copied"? What would make that happen?

Are you saying that setting a config option inline doesn't create a class instance of proxy like Ext.create does?

mitchellsimoens
10 Jan 2012, 8:48 AM
Copied... meaning copy one object to create a clone of it so now you have two different ones. When a store is created, if the proxy is set to an object, it creates a proxy instance based on that config object. If it is set to a proxy instance, then it will not convert so therefore if it's an instance, it will always use the instance set to it.

quaidbrown
10 Jan 2012, 9:01 AM
So how would you recommend extending the proxy class and using it in a store? If I set my own type property in the class definition of my proxy subclass would the loader somehow find my class when I use that type in a config object?

mitchellsimoens
10 Jan 2012, 9:10 AM
You should set the alias property to a custom type:


alias: 'proxy.myajax'

Then you can do:


proxy : {
type : 'myajax'
}

slemmon
10 Jan 2012, 9:47 AM
Skirtle mentioned using that same syntax for store:
alias: 'store.mystore'

store {
type: 'mystore'
}

Looks like that convention works with the aliases of proxies, readers, stores, and models (and components have their own of xtype and plugins have ptype), right?

quaidbrown
10 Jan 2012, 10:16 AM
Ok, I tried this. Any insights regarding "cannot call method 'substring' of undefined." It seems to be the most common error I get when I do something that's "not okay" but it isn't very meaningful.

Also, why proxy.myajax? Does the proxy part correlate to the package or folder structure? Would it matter what I put there? How does type : myajax resolve to proxy.myajax?

Sorry for the rapid fire low level questions but this is the stuff that hangs me up most often. If you know of some documentation that clarifies these kinds of things that would be great.

I really appreciate you taking the time to think about this and sharing your experience.

app/proxy/AppointmentAjaxRemoteProxy.js

Ext.define('AM.proxy.AppointmentAjaxRemoteProxy',{
extend: 'Ext.data.proxy.Ajax',
alias : 'proxy.myajax',

api: {
create : '/SchedulingService/Appointment/SetAppointment/SetAppointment',
read : '/SchedulingService/Appointment/Appointments',
update : '/SchedulingService/Appointment/SetAppointment/SetAppointment',
destroy : '/SchedulingService/Appointment/SetAppointment/SetAppointment'
},
reader: {
type: 'json',
root: 'GetAppointmentsResult',
successProperty: 'success'
}
});



app/store/AppointmentStore.js

Ext.define('AM.store.AppointmentStore',{
extend: 'Ext.data.Store',
model: 'AM.model.AppointmentModel',
autoLoad: true,

proxy:{
type: 'myajax' //I also tried type: 'proxy.myajax', 'myajax2' and 'proxy.myajax2' to check for reserved words
}
//Ext.create('AM.proxy.AppointmentAjaxRemoteProxy')

});


Here's what my console shows



Uncaught TypeError: Cannot call method 'substring' of undefined
Ext.ClassManager.parseNamespace ext-all-debug.js:3647
Ext.ClassManager.get ext-all-debug.js:3744
Ext.ClassManager.instantiate ext-all-debug.js:3910
Ext.ClassManager.instantiateByAlias ext-all-debug.js:3898
(anonymous function) ext-all-debug.js:1555
Ext.define.setProxy ext-all-debug.js:44383
Ext.define.constructor ext-all-debug.js:44348
Base.callParent ext-all-debug.js:2891
Ext.define.constructor ext-all-debug.js:44877
Ext.Class.newClass ext-all-debug.js:3188
(anonymous function)
Ext.ClassManager.instantiate ext-all-debug.js:3948
(anonymous function) ext-all-debug.js:1555
Ext.define.getStore ext-all-debug.js:39754
Ext.define.getStore ext-all-debug.js:19757
(anonymous function) ext-all-debug.js:1548
(anonymous function) ext-all-debug.js:19698
Ext.Array.each ext-all-debug.js:953
Ext.define.createGetters ext-all-debug.js:19684
Ext.define.constructor ext-all-debug.js:19668
Ext.Class.newClass ext-all-debug.js:3188
(anonymous function)
Ext.ClassManager.instantiate ext-all-debug.js:3948
(anonymous function) ext-all-debug.js:1555
Ext.define.getController ext-all-debug.js:39739
(anonymous function) ext-all-debug.js:39691
isEvent ext-all-debug.js:10516
fire ext-all-debug.js:10658
Ext.EventManager.onDocumentReady ext-all-debug.js:10780
Ext.Loader.onReady.fn ext-all-debug.js:4816
Ext.Loader.triggerReady ext-all-debug.js:4797
(anonymous function) ext-all-debug.js:1548
Ext.Loader.require ext-all-debug.js:4701
Ext.Loader.triggerReady ext-all-debug.js:4791
Ext.Loader.refreshQueue ext-all-debug.js:4473
Ext.Loader.refreshQueue ext-all-debug.js:4504
Ext.Loader.refreshQueue ext-all-debug.js:4504
Ext.Loader.onFileLoaded ext-all-debug.js:4747
(anonymous function) ext-all-debug.js:1548
Ext.Loader.injectScriptElement.onLoadFn


And from the debugger, here's the line where it dies.

parseNamespace: function(namespace) {


var cache = this.namespaceParseCache;


if (this.enableNamespaceParseCache) {
if (cache.hasOwnProperty(namespace)) {
return cache[namespace];
}
}


var parts = [],
rewrites = this.namespaceRewrites,
rewrite, from, to, i, ln, root = Ext.global;


for (i = 0, ln = rewrites.length; i < ln; i++) {
rewrite = rewrites[i];
from = rewrite.from;
to = rewrite.to;


if (namespace === from || namespace.substring(0, from.length) === from) {//dies there
namespace = namespace.substring(from.length);


if (typeof to !== 'string') {
root = to;
} else {
parts = parts.concat(to.split('.'));
}


break;
}
}


parts.push(root);


parts = parts.concat(namespace.split('.'));


if (this.enableNamespaceParseCache) {
cache[namespace] = parts;
}


return parts;
}

quaidbrown
10 Jan 2012, 10:32 AM
And to answer one of my own questions I see that AbstractStore's setProxy method hardcodes 'proxy.' before the proxy.type with this line:

proxy = Ext.createByAlias('proxy.' + proxy.type, proxy);

quaidbrown
11 Jan 2012, 7:21 AM
I fixed this by using:


requires : ['AM.proxy.AppointmentAjaxRemoteProxy']

However, now that it works in a separate class I have my original problem again. The api:{} block isn't used.