PDA

View Full Version : How to extend a Model



AndreaCammarata
25 Mar 2011, 11:48 PM
Hi guys,
does anyone know if is possibile to extends an existing model using something like, for example




Ext.regModel('Product', {
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
});

Ext.ModelMgr.extends('Product', 'Book', {
fields: [
{name: 'author', type: 'string'},
{name: 'pages', type: 'int'}
]
});
In this way I would have my Book model which inherit fields from "Product" ad implements some new fields. Is this already possibile to do?

Thank you guys

jay@moduscreate.com
29 Mar 2011, 4:38 AM
There is nothing that I'm aware of in the framework that provides that functionality.

AndreaCammarata
29 Mar 2011, 4:48 AM
There is nothing that I'm aware of in the framework that provides that functionality.

Thank you for your reply garcia.
It would be really useful if Sencha develop this functionality.
Every OOP language should be able to provide this feature, like we are already able to do for Sencha components.

jay@moduscreate.com
29 Mar 2011, 4:51 AM
Sencha is not an OOP Language, JavaScript is.

That said, Models are not classes. :(

jay@moduscreate.com
29 Mar 2011, 4:52 AM
FWIW, I think it would be good to add to the framework, though I've never had a need to do this.

AndreaCammarata
29 Mar 2011, 5:01 AM
Sencha is not an OOP Language, JavaScript is.

That said, Models are not classes. :(

Maybe I've not express myself in the right way.
Yes, you are right javascript is OOP, but saying what you say do you mean that Sencha is not?
Does not Sencha take the best from the language it is build on?
I think yes, because we can use great features like



Ext.extends


and



Ext.override


So why not do the same with models?
I'm working on some BIG Sencha Touch projects, and, sometimes, for example, I just want that the server gives me back the json data for a BASE model, because I don't want make a massive use of network for data I don't need.
When I really need to take all the data for that object (example a Product), I want the server gives me back all the informations about it, so the COMPLETE model.
I don't know if I was able to let you understand my needs.

Bucs
29 Mar 2011, 5:40 AM
So why not have overrides on the server methods that return limited sets of Product information, so you can call these when you only need limited data? The model is already on the client, so all you do is populated it with the limited data.

Or, to organize it better, create object properties to hold the data that you may not need every time, and only populate it when needed. I am using MVC on the server and the client, and it would be trivial to add a property on the server model for say something like "Product.ExtendedInfo", which is of type ExtendedInfo that in turn is an object that has a lot more extraneous product detail info that may not be needed in every call. Then have your methods populate this object on the server depending on your needs. When it's brought to the client an serialized back into the model as an property of type 'auto', your ExtendedInfo property is either fully populated for use (like on a Product Detail page), or is null when not needed for say a ProductList page that only needs limited data.

Not a true OO approach, but would more than suffice. Otherwise, you're probably going to have to try to play around with the prototype of the model I'm guessing, but that could get ugly, and not worth the effort imo.

AndreaCammarata
29 Mar 2011, 5:48 AM
Really thank you for your detailed reply Bucs.
This could be a good compromise for my needs about Base and Complete models.
But how you would handle the model for example "Book" that extends "Product"?
I would really have a way to keep all the fields and even functions defined inside the "Product" model even inside the "Book" one.
This would be really OO ;)

Bucs
29 Mar 2011, 6:21 AM
You might want to try to create Sencha models on the client to isolate your required property sets into their own models, then use the hasMany (even though it's only a one to one relationship) and belongs to, to establish the required relationships. Then, if you implement overrides on the server data calls to return the required information sets, you will fill the appropriate models as needed.

This would at least let you segregate model specific properties and functions into separate entities.

So something like:


Ext.regModel("Product", {
idProperty: "Id", //defaults to 'id'
fields: [
{ name: "Id", type: "string" },
{ name: "Type", type: "string" },
{ name: "Desc", type: "string" },
{ name: "Price", type: "string" }
],

hasMany: {model: 'Book', name: 'Books'}

});

Ext.regModel("Book", {
idProperty: "BookId", //defaults to 'id'
fields: [
{ name: "BookId", type: "string" },
{ name: "Genre", type: "string" },
{ name: "Author", type: "string" },
{ name: "Pages", type: "int" }
],

belongsTo: 'Product'

});



Then is Product.Type = 'Book' you could do Book specific processing, or call Book specific functions. Again, I would have to say that Products in general tend to have enough common properties between them where this should not be necessary, but maybe that will help get you closer to what you're trying to do...until Sencha decides to allow model extension, or you figure out a clean way to use the model's prototype to accomplish this :)

Iosis
29 May 2011, 11:38 PM
Still no suitable solution to this ?
Its could be very usefull for big application.

Hanni Sullivan
30 May 2011, 1:38 AM
I'm facing the same problem right now and one solution I'm considering is the factory pattern (http://2007-2010.lovemikeg.com/2009/06/26/the-factory-pattern-in-javascript/). This could be a way to create a lot of very similar models.

stever
31 May 2011, 5:29 PM
I'm not too sure of the full utility, but in your case why not this approach?



ProductFields = [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
];

Ext.define('Product', {
extend: "Ext.data.Model",
fields: ProductFields
);

Ext.define('Book', {
extend: "Ext.data.Model",
fields: ProductFields.concat([
{name: 'author', type: 'string'},
{name: 'pages', type: 'int'}
])
});

Hanni Sullivan
31 May 2011, 10:25 PM
Hey Steve, nice solution. It still looks a bit hackish, but it is certainly way better than my idea.

Hanni Sullivan
8 Jul 2011, 3:11 AM
I just looked at the source code of the "registerType" method of the Ext.ModelMgr. And what do I see? The method is looking for an "extend" config element.
This mean you can extend a model quite easily.

I guess it works like this:



Ext.regModel('person', {
fields: [{
name: 'name',
type: 'string'
}, {
name: 'age',
type: 'number'
}]
});

Ext.regModel('user', {
fields: [{
name: 'id',
type: 'string'
}, {
name: 'password',
type: 'string'
}],

extend: 'person'
});


The API documentation could be slightly informative about matters like this. It states:


Parameters:
None.


for the "registerType" method, which obviously makes no sense at all.

atwoodjw
29 Aug 2011, 7:49 PM
Using the "extend" config element looks very promising, but I'm seeing a weird issue when extending a base model more than 1x.



Ext.regModel('Base', {
proxy: {
type: 'ajax',
url: '/auctionService.do',
actionMethods: {
read: 'POST'
},
extraParams: {
action: 'search'
},
reader: {
type: 'xml',
root: 'data',
record: 'result'
}
},
fields: []
});


Ext.regModel('Buyer', {
extend: 'Base',
fields: [...]
});


Ext.regModel('Seller', {
extend: 'Base',
fields: [...]
});

MyApp.BuyerList = Ext.extend(Ext.List, {
store: Ext.StoreMgr.get('BuyerStore'),
itemTpl : '{name}'
});


Ext.reg('BuyerList', MyApp.BuyerList);



With the Seller model commented out, the BuyerList displays correctly, but with the code present, the request comes back correctly, but the List is rendered empty.

Has anyone extended sucessfully?

darthwes
31 Aug 2011, 5:16 PM
@atwoodjw, I tried your example and it works for me. CNR! 'extend' FTW!

I set autoLoad to true, though...