PDA

View Full Version : Help creating a custom Model to extend from?



delebash
7 May 2013, 12:40 PM
ExtJs 4.2 using MVC architecture

I am try to create a Model that all other models will inherit the properties but having trouble getting it working.

In my model folder I have a Contact.js that defines a contact model

Code for Contact Model


Ext.define('SimplyFundraising.model.Contact', {
extend : 'Ext.data.WakandaModel'
});


In my index.html I include scripts to Ext.data.proxy.Wakanda.js and Ext.data.WakandaModel.js

Code for data.WakandaModel


Ext.define('Ext.data.WakandaModel', {

extend: 'Ext.data.Model',

idProperty: '__KEY',

stampProperty: '__STAMP',

defaultProxyType: 'wakanda',
});


So my understanding is that in my Contact model by using extend : 'Ext.data.WakandaModel', then the Contact model should include the properties of the WakandaModel which in turn extends from Ext.data.Model, however this is not the case. No proxy is defined for the Contact model. So I am not sure what I am doing wrong in trying to make the custom model class.

I reference Ext.data.proxy.Wakanda using defaultProxyType: 'wakanda'
Code for proxy.Wakanda


Ext.define('Ext.data.proxy.Wakanda', {

extend: 'Ext.data.proxy.Rest',

alternateClassName: 'Ext.data.WakandaProxy',

alias : 'proxy.wakanda',

sortParam: '$orderby',

filterParam: '$filter',

startParam: '$skip',

limitParam: '$top',

reader: 'wakanda',

writer: 'wakanda',

actionMethods: {
create : 'POST',
read : 'GET',
update : 'POST',
destroy: 'POST'
},

buildUrl: function(request) {
debugger;
var modelName = this.model.modelName,
operation = request.operation,
records = operation.records || [],
record = records[0],
id = record ? record.getId() : operation.id,
url = '/cors/' + modelName,
action = request.action;

if (this.appendId && id && (action === 'read' || action === 'destroy')) {
url += '(' + id + ')';
}

request.url = url;

// console.log("buildUrl", this, arguments, request.url);


if (action !== 'read') {
if (action === 'create') action = 'update';
else if (action === 'destroy') action = 'delete';
url = Ext.urlAppend(url, '$method=' + action);
}

if (this.noCache) {
url = Ext.urlAppend(url, Ext.String.format("{0}={1}", this.cacheString, Ext.Date.now()));
}

return url;
},

encodeSorters: function(sorters) {
var min = [],
length = sorters.length,
i = 0, sort = '';

for (; i < length; i++) {
sort += sorters[i].property + ' ' + sorters[i].direction + ' ';
}

return sort;
},

encodeFilters: function(filters) {
var min = [],
length = filters.length,
i = 0, filter = '';

for (; i < length; i++) {
filter += filters[i].property + ' eq ' + filters[i].value + '@ ';
}
return filter;
}

});



Any help is appreciated!

Thanks,
Dan

jay@moduscreate.com
7 May 2013, 5:36 PM
Dan, keep away from writing to the Ext. namespace.

Also, you should not be including scripts in your index.html file. it should be done via Ext JS loader.

delebash
7 May 2013, 6:41 PM
Thanks,

Regarding the loader, I just have not read up on that yet, it is on the todo list and I know it is the proper way to load scripts.

Regarding the namespace so instead of defining Ext.data.WakandaModel is should use say my apps namespace SimpyFundraising.WakandaModel. Correct?

In regards to my problem of not getting my custom extended model to inherit the properties, I ran a test using this code and I can see the inheritance working as expected. BusinessUser does pick up the fields from User, however I still can't get this to work in my real app using the code in my first post.



<html>
<head>
<title>Simply Fundraising</title>

<link rel="stylesheet" type="text/css" href="lib/ext4/resources/css/ext-all-debug.css">
<link rel="stylesheet" type="text/css" href="css/app.css">

<script type="text/javascript" src="lib/ext4/ext-all-dev.js"></script>


</head>
<body>
<script>
Ext.define('User', {
extend: 'Ext.data.Model',

idProperty: '__KEY',

stampProperty: '__STAMP',

defaultProxyType: 'wakanda',

fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true}
],
});

Ext.define('BusinessUser', {
extend: 'User',
fields: [
{name: 'businessType', type: 'string'},
{name: 'company', type: 'string'}
]
});
//debugger;
// instantiating a User object
var u = Ext.create('User', {
name: 'John Doe',
age: 30,
phone: '555-5555'
});

// instantiating a BusinessUser object
var bu = Ext.create('BusinessUser', {
name: 'Jane Doe',
age: 40,
phone: '555-5556',
businessType: 'analyst',
company: 'ACME'
});
debugger;
console.log(Ext.getClassName(bu)); // "BusinessUser"
console.log(Ext.getClassName(u)); // "User"
console.log(u instanceof User); // true
console.log(bu instanceof User); // true
console.log(u instanceof BusinessUser); // false
console.log(bu instanceof BusinessUser); // true
console.log(u instanceof Ext.data.Model); // true
console.log(bu instanceof Ext.data.Model); // true
console.log(u instanceof Ext.data.Store); // false, just to check if it's not returning true for anything
console.log(bu instanceof Ext.data.Store); // false
console.log("name" in u.data); // true
console.log("name" in bu.data); // true
console.log("company" in u.data); // false
console.log("company" in bu.data); // true
</script>
</body>
</html>


Further attempts to find the problem

My controller is defined like

Controller snippet


Ext.define('SimplyFundraising.controller.Contacts', {
extend : 'Ext.app.Controller',
// models : ['Contact','User'],
stores : ['Contacts'],

views : ['contacts.List', 'contacts.Edit'],
init : function() {
this.control({
'contactslist' : {
itemdblclick : this.editContact,
removeitem : this.removeContact
},
'contactslist > toolbar > button[action=create]' : {
click : this.onCreateContact
},
// 'contactsadd button[action=save]': {
// click: this.doCreateContact
// },
'contactsedit button[action=save]' : {
click : this.updateContact
}
});
},
list : function() {
// var mystore = Ext.StoreMgr.lookup('Contacts');
// var myContact = this.getModel('Contact')
// var User = this.getModel('User');

debugger;
var mystore = this.getStore("Contacts");
debugger;
// mystore.proxy.api.read = users.proxy.api.read + '(17)'
//mystore.proxy.extraParams = { $expand: 'ContactType'};
mystore.load();
//var test = Ext.ModelManager.getModel('Contact');

// //var User = this.getContactModel();
// User.load(258, {
// success: function(user) {
// console.log("Loaded user 258: " + user.get('lastName'));
// }
// });
},


In the debugger if I look at mystore.model, the model is using default Ext.data.model properties and not properties from WakandaModel. If I look at the superclass, mystore.model.superclass, I see the class Ext.data.WakandaModel which is correct and it has the correct properties as expected, but I don't understand why my Contact model is not inheriting the WakandaModel.

Contacts Store code


Ext.define('SimplyFundraising.store.Contacts', {
extend : 'Ext.data.Store',
model : 'SimplyFundraising.model.Contact',
autoLoad : false,
autoSync : true
});


UPDATE:
Ok getting a little better understanding of the MVC flow but still confused on how things are automatically created or not.

In my Contact Controller I use this to load my data
var mystore = this.getStore("Contacts");
mystore.load();

If my contact model isn't extended with my WakandaModel and everything ie proxy ect is defined directly in my Contact Model that now just extends using Ext.data.model, it works fine

This is exactly how the MVC example is setup except that the store is set to autoload where I load mine manually.

The problem is when extending my Contact Model to use the WakandaModel.

For testing I can call in my Contact Controller

var mycontact= Ext.create('SimplyFundraising.model.Contact')
and this does create the correct Contact Model with inherited properties from WakandaModel.

So creating mystore that references Contact model that uses the default Ext.data.model works fine. But when using the same statement to create a store that references Contact model which inherits from a custom model that custom model is not being created. Or at least that is what seems to be happening. Not really sure, but at least I can prove that if I just create the Contact Model directly and not via a store creation, the model is correct.

Any more suggestions are welcome.
Thanks,
Dan


Thanks again for your help,
Dan

delebash
9 May 2013, 12:31 PM
Well still don't understand why this is not working any help in creating a custom model using the mvc patter?