PDA

View Full Version : Override functions in my Model and call the base class?



wizkid
4 Mar 2011, 6:26 PM
I am new to Extjs and I am not quite sure how to go about this syntactically.

First consider this model definition:




Ext.regModel('User',
{
fields: [
{ name: 'LoginUserId', type: 'string' },
{ name: 'FirstName', type: 'string' },
{ name: 'LastName', type: 'string'},
{ name: 'IsNew', type: 'boolean', defaultValue: true },
{ name: 'IsDirty', type: 'boolean', defaultValue: true },
{ name: 'IsDeleted', type: 'boolean', defaultValue: false }],

proxy:
{
type: 'rest',
url: '/Home/Index2/'

}

});



When I call:
Ext.ModelMgr.create(..., "User");

I want my fields "IsNew" and "IsDirty" set to true and then call the Extjs base class and
create my model. You might say why don't you use defaultValue in this case.
Yes, but I posted a bug for it. It does not look like defaultValue
is working right, yet... Ok...

The other function I want to override is user.set('FirstName', "Dolly");

When this is called I want IsDirty to be set to true and then go ahead and call the base
class and set my property.

Next, I want to call user.destroy() and, predictably, set IsDeleted to true in a similar
fashion to .set (call the base afterwards).

For the .create that might require a separate class definition with a override? I guess
I am just not sure where to start with the syntax. I am new at this.

Also, for the .set and .destroy functions I would assume these overrides could go directly on the model?

I might mention I want to have these fields (IsDirty, IsNew, IsDeleted) always on my models.
So, what would be the right way to go about this and how?

icflorescu
5 Mar 2011, 5:04 AM
I'm new with ExtJS myself and I'm afraid I can't help you with a straightforward solution... Conceptually speaking, what you're looking for is a kind of "base model" that each of your model classes will extend. At least that's how I use to do it on the server-side in PHP or .NET anyway.

But going back to defaultValue bug, I would simply wait for it to get fixed instead of coding workarounds. I trust this is the kind of bug that will get fixed before the final release.
In theory the models in the new ExtJS data package already have the functionality you're looking for so I see no point of reinventing the weel, wouldn't you agree?...

wizkid
5 Mar 2011, 7:08 AM
For the defaultValue bug I would agree with you there.

I also agree with you in theory ExtJS's model probably has these kind of properties.

But in my situation I would really like to have these properties on my model due to automatic serialization and deserialization with my ASP.NET MVC Server side code. The model / business object framework I use is CSLA. These properties are vital to come down/up to my server as this is how CSLA will automatically know what "dataportal" method to call. Be it a update, insert, delete. So, in my particular case replicating these properties on the client, and having them automatically set would be huge for me.



Ext.override(Ext.data.Model,
{
set: function (arguments, value)
{
Ext.data.Model.superclass.set.call(this, arguments, value);
}
}


I have been reading how to do this. You can do override or extend. Override does not have an analog in C# .NET or Java. Plugging this code in will magically take over for my model class. However, the side effect is every model will use this set method. I would rather not do that... But to extend the class correctly looks tricky to me...

Anyway the above code does get called. But somehow it not working right. It's not setting any of my properties when I call my proxy load... So something is wrong with Ext.data.Model.superclass.set.call(this, arguments, value);

Oh well I will keep plugging along until a expert comes along!

wizkid
5 Mar 2011, 11:24 AM
Yay, I got override to work for me...



Ext.override(Ext.data.Model,
{
set: function (fieldName, value)
{
if(value)
Ext.data.Model.superclass.set.call(this, fieldName, value);
else
Ext.data.Model.superclass.set.call(this, fieldName);
}

});


My problem was I was passing a value in when I should not of. When value is "undefined" passing it in messed up the superclass definition call because they used "arguments" array length to check if we were coming from a proxy load event or a regular caller setting a field. So, passing value in as "undefined" made it skip a whole bunch of logic. I don't know if there is a cleaner way of checking this condition in one line. A inline if does not work because what would I pass in, in the "undefined" case?

So, at least I can override something. That is a good thing! I would feel more comfortable extending it though. I will play around with it some more. I am glad that I have the source code! Yay for JavaScript!

wizkid
5 Mar 2011, 12:57 PM
Boy do I feel like a total newb! I started debugging through ExtJs's code and had a epiphany!



Ext.regModel('User',
{
fields: [
{ name: 'LoginUserId', type: 'string' },
{ name: 'FirstName', type: 'string' },
{ name: 'LastName', type: 'string' },
{ name: 'IsNew', type: 'boolean' },
{ name: 'IsDirty', type: 'boolean' },
{ name: 'IsDeleted', type: 'boolean'}],

proxy:
{
type: 'rest',
url: '/Home/Index2/'

},

set: function (fieldName, value)
{
if (value)
{
if (fieldName != "IsDirty")
Ext.data.Model.superclass.set.call(this, "IsDirty", true);

Ext.data.Model.superclass.set.call(this, fieldName, value);
}
else {

Ext.data.Model.superclass.set.call(this, fieldName);
}
}

});


Basically I realized that this regModel factory method was actually creating a extended class of Model....

So just put your override in there! Simple as pie! Thanks extjs! Very fancy OOP for JavaScript if I do say so myself. I am just glad nobody replied with an answer yet, as now I get the total satisfaction I can read extjs's source code on my own :D

wizkid
5 Mar 2011, 2:27 PM
Oh yeah... One last thing for my particular case .set is called by load as it is constructing my model... This of course is bad because I don't want to set my IsDirty property in this case... So we need to extend the constructor a little bit... That took a little digging but this might help someone in the future:



Ext.regModel('User',
{
fields: [
{ name: 'LoginUserId', type: 'string' },
{ name: 'FirstName', type: 'string' },
{ name: 'LastName', type: 'string' },
{ name: 'IsNew', type: 'boolean' },
{ name: 'IsDirty', type: 'boolean' },
{ name: 'IsDeleted', type: 'boolean'}],

proxy:
{
type: 'rest',
url: '/Home/Index2/'

},

constructor: function ()
{
this.isContructing = true;
Ext.data.Model.prototype.constructor.apply(this, arguments);
this.isContructing = false;
},

set: function (fieldName, value)
{
if (value)
{
Ext.data.Model.superclass.set.call(this, fieldName, value);

if (!this.isContructing && fieldName != "IsDirty")
Ext.data.Model.superclass.set.call(this, "IsDirty", this.dirty);

}
else {

Ext.data.Model.superclass.set.call(this, fieldName);
}
}

});