BelongsTo with ExtJS Model - javascript

I have two Models: "Identity" and "Profile". The identity 'belongsTo' profile. When I get a record of type 'identity', I want to (by this record) get the correspondent profile. I'm trying using the following code:
Ext.define('App.model.Identity', {
extend: 'Ext.data.Model',
fields: [
// ...
{name: 'id_profile', type: 'int'},
// ...
],
belongsTo: {
model: 'App.model.Profile',
primaryKey: 'id',
foreignKey: 'id_profile',
associatedName: 'Profile'
},
proxy: {
type: 'ajax',
api: {
read: App.Config.getBaseUrl() + '/admin_identity/list',
create: App.Config.getBaseUrl() + '/admin_identity/create',
update: App.Config.getBaseUrl() + '/admin_identity/update',
destroy: App.Config.getBaseUrl() + '/admin_identity/destroy'
},
reader: {
type: 'json',
root: 'data'
}
}
});
Ext.define('App.model.Profile', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
// ...
],
belongsTo: {
model: 'App.model.Identity',
primaryKey: 'id',
foreignKey: 'id_profile',
name: 'identities'
},
proxy: {
// ...
}
});
When I try to do this:
function viewProfile(identity) {
identity.getProfile(function(profile){
console.log(profile);
});
}
What I get is an empty profile's object. The strange thing is that the Identity class didn't do any http request to get the profile. I'm doing this right?
Thanks in advance

Have you tried:
identity.getProfile({
success:function(profile, operation){
},
failure: function(profile, operation){
//check for a failure
}
});
I would also try removing the associatedName property.

Related

ExtJs: load a single gird from two different APIs

I have two entities, sent from two different APIs, with a one to one relationship.
I want to load both models in the same grid panel. The problem is that I can only load one store. To load the other store, I attached a callback to the grid reload event which edits the grid DOM manually to insert data form the second store.
My Question is: Can I load both the model and the association without using DOM hacks like I did?
The entities from APIs look like this:
Get /Users/Details:
{
"Id" : "55b795827572761a08d735ac",
"Username" : "djohns",
"Email" : "admin#mail.com",
"FirstName" : "Davey",
"LastName" : "Johns"
}
And:
Get /Users/Rights:
{
"_id" : "55b795827572761a08d735ac",
"Status" : "Activated",
"Roles" : [
"portal",
"dataApp"
]
}
Notice the same id, which is used in the API as the key/foreign key).
Now these are the models:
Ext.define('Portal.model.users.UserRights', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
mapping: 'Id'
},
{
name: 'Status'
},
{
name: 'UserId',
mapping: 'Id',
reference: 'Portal.model.users.UserDetails'
}
],
schema: {
namespace: 'Portal.model.users',
proxy: {
type: 'rest',
url: Portal.util.Util.constants.apiBaseURL + 'Users/Rights',
reader: {
type: 'json',
rootProperty: 'Objects'
}
}
}
});
And:
Ext.define('Portal.model.users.UserDetails', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
mapping: 'Id'
},
'FirstName',
'LastName',
'Username',
'Email'
],
});
And I defined a store for user details (while the store of the user rights is inside its own model):
Ext.define('Portal.store.UsersDetails', {
extend: 'Ext.data.Store',
model: 'Portal.model.users.UserDetails',
proxy: {
type: 'rest',
url: Portal.util.Util.constants.apiBaseURL + 'Users/Details',
reader: {
type: 'json',
rootProperty: 'Objects'
}
}
});
Here is how I configured the Grid:
Ext.define('Portal.view.users.UsersGrid', {
extend: 'Ext.grid.Panel',
store: 'UsersDetails',
columns: [
{
dataIndex: 'id',
text: 'Id'
},
{
dataIndex: 'Username',
text: 'Username'
},
{
dataIndex: 'Email',
text: 'Email'
},
{
dataIndex: 'FirstName',
text: 'First Name'
},
{
dataIndex: 'LastName',
text: 'Last Name'
},
{
text: "Status",
cls: "status-column",
renderer: function (value, meta, record) {
return "loading...";
}
}
],
loadUserRights: function () {
var columns = this.getEl().select('.status-column');
var cells = this.getEl().select(".x-grid-cell-" + columns.elements[0].id + " .x-grid-cell-inner");
data = this.getStore().getData();
Ext.each(data.items, function (record, index) {
var userRights = record.userUserRights();
userRights.load({
callback: function (records, operation, success) {
if (success) {
cells.elements[index].innerText = userRights.data.items[0].data.Status;
}
}
});
});
}
});
And then I load the gird from an external function:
grid.getStore().reload({
callback: function (records, operation, success) {
grid.loadUserRights();
}
});

Ext Js: How to load a store from List<String>

This is my JSON data returned from the server. I am not seeing my combo getting loaded. What is wrong here?
{"suffixList":["-1","-2","-3"]}
Model:
Ext.define('ExtMVC.model.Suffix', {
extend: 'Ext.data.Model',
fields: [
{name: 'suffix'}
]
});
Store:
Ext.define('ExtMVC.store.Suffixes', {
extend: 'Ext.data.Store',
model: 'ExtMVC.model.Suffix',
autoLoad : false,
proxy: {
type: 'ajax',
url: 'http://'+window.location.host+'/populateCombo',
reader: {
type: 'json',
root: 'suffixList'
}
}
});
View:
{
xtype:'combo',
id: 'suffix',
name: 'suffix',
store : 'Suffixes',
displayField: 'suffix',
valueField: 'suffix'
}
You can use an ArrayStore
new Ext.data.ArrayStore({
fields: ['suffix'],
data: {suffixList: ['-1', '-2', '-3']},
proxy: {
type:'memory', //'ajax'
reader: {
type: 'array',
root: 'suffixList'
}
}
})
The data is not formatted correctly. Each record should be an object, with properties for the store's fields. In your case, the data should look like this:
{"suffixList":[{"suffix": "-1"},{"suffix": "-2"},{"suffix": "-3"}]}

ExtJS configure store to write list of models under a property name

I have a model like this:
Ext.define('Policy', {
extend: 'Ext.data.Model',
fields: [
{
name: 'id',
type: 'sting',
phantom: true,
convert: function(value, record) {
return record.get('a') + '#' +
record.get('b');
}
},
{name: 'a', type: 'string'},
{name: 'b', type: 'string'}]
});
Where the PK of each record is a and b. The store looks like this:
Ext.define('Store', {
extend: 'Ext.data.Store',
model: 'Policy',
autoLoad: true,
proxy: {
type: 'rest',
simpleSortMode: true,
batchActions: true,
reader: {
type: 'json',
root: 'data',
idProperty: 'id'
},
writer: {
nameProperty: 'mapping'
},
api: {
create:'/batch',
read: '/policies',
update: '/batch',
destroy: '/batch'
}
}
});
How can I configure the store so that when it POSTS to /batch when calling store.sync(), the payload looks like this and only consists of dirty records:
{
"policies": [{
"a": "AA",
"b": "BB",
}, {
"a": "AAA",
"b": "BBB"
},...]
}
where there is a policies property and under it is an array of dirty policies.
You can create whatever structure you want by making a manual Ext.Ajax() call. You have to submit only the dirty records yourself.

Sencha Store proxy is not getting called

I want to load store data dynamically and don't want to use model for this. if I provide data list gets populated but if I use store's proxy it doesn't get called and url is not getting hit. Please help.
Ext.define('TrainEnquiry.view.SearchTrainResults', {
extend: 'Ext.List',
xtype: 'searchedtrainresult',
requires: 'Ext.data.proxy.JsonP',
config: {
itemId: 'searchedtrainresult',
title: 'Train Result:',
itemTpl: '<div class="myContent">'+
'<div><b>{number}</b> </div>' +
'</div>',
store: {
fields: ['number'],
/*data: [
{number: 'Cowper'},
{number: 'Everett'},
{number: 'University'},
{number: 'Forest'}
]*/
proxy: {
url: 'http://abc.amazonaws.com/search.json',
type:'jsonp',
extraParams : {
'q' : '12313'
},
reader: {
type: 'json',
},
success: function() {
debugger;
console.log('success');
},
failure: function() {
debugger;
console.log('failure');
}
}
},
onItemDisclosure: true
}
});
I think your "fields" config option needs to be a proper Ext.data.Field object, so maybe this would work:
Ext.define('TrainEnquiry.view.SearchTrainResults', {
...
config: {
...
store: {
fields: [ { name: 'number', type: 'string'} ],
proxy: {
...
}
},
...
}
});
(Reference from Sencha forums)
You could try removing the pageParam and startParam from your proxy. Just like this
Ext.create('Ext.data.Store', {
storeId:'UserStore',
autoLoad: true,
model: 'UserModel',
proxy: {
type: 'jsonp', // Because it's a cross-domain
url : 'https://api.twitter.com/1/lists/members.json?owner_screen_name=Sencha&slug=sencha-team&skip_status=true',
reader: {
type: 'json',
root: 'users' // The returned JSON will have array
// of users under a "users" property
},
// Removing pageParam and startParam
pageParam: undefined,
startParam: undefined
}
});
Here is an example http://jsfiddle.net/alexrom7/YNTuN/
Try changing the type of your proxy store to Ajax (type: 'ajax'). Just like this
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url: '/test.json',
reader: {
type: 'json',
}
},
autoLoad: true
});

Load JSON in Ext store, associations missing

I'm using Ext 4.1. I have some issues with loading json data with associations. The flat data gets loaded perfectly, only the 'hasMany' doesn't work. (if loaded there nowhere to be found). If a record is loaded I want to be able to get the 2 stores of Attendee's and the 1 store of documents.
I can also change the JSON format to a better format (if you have suggestions let me know!)
I have this json data.
This is my first model:
Ext.define('App.model.package.LabVisit', {
extend: 'Ext.data.Model',
requires: [
'App.model.package.Attendee',
'App.model.package.Document'
],
idProperty: 'labVisitID',
fields: [
{
mapping: 'lab_visit_id',
name: 'labVisitID',
type: 'int'
},
{
mapping: 'lab_id',
name: 'labID',
type: 'int'
},
... some more irrelevant...
{
mapping: 'comments',
name: 'comments'
},
{
name: 'upddate'
}
],
hasMany: [
/* edit: added foreignKey (also tried with: lab_visit_id) */
{ model: 'package.Attendee', name: 'attendeeLabList', associationKey:'attendee_lab', foreignKey: 'labVisitId' },
{ model: 'package.Attendee', name: 'attendeeEmpList', associationKey:'attendee_emp', foreignKey: 'labVisitId' }
{ model: 'package.Document', name: 'document', associationKey:'document' },
]
});
I have following attendee model:
Ext.define('App.model.package.Attendee', {
extend: 'Ext.data.Model',
fields: [
/* edit: added this field */
{
mapping: 'lab_visit_id',
name: 'labVisitId'
},
{
mapping: 'attendee_id',
name: 'AttendeeID'
},
{
mapping: 'first_name',
name: 'firstName'
},
{
mapping: 'last_name',
name: 'lastName'
},
{
name: 'email'
}
]
});
following document model:
Ext.define('App.model.package.Document', {
extend: 'Ext.data.Model',
fields: [
{
mapping: 'document_id',
name: 'docID'
},
{
mapping: 'document_name',
name: 'docName'
},
{
mapping: 'document_mimetype',
name: 'mimeType'
},
{
name: 'uploadID'
}
]
});
Finally my store:
Ext.define('App.store.package.LabVisit', {
extend: 'Ext.data.JsonStore',
requires: [
'App.model.package.LabVisit'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.merge({
storeId: 'labVisitStore',
model: 'App.model.package.LabVisit',
remoteSort: true,
proxy: {
type: 'ajax',
api: {
read: API_URLS.getVisitList //url to the json
},
reader: {
type: 'json',
root: 'rows'
}
}
}, cfg)]);
}
});
Edit:
I've added the foreign key in the model and added it to the hasMany
Still no difference. This is my output:
I also find it a strange: If it's broken I expect an exception. And there are 2 mysterious stores always present but I don't have a clue why or what's the purpose.
The problem was in this part:
hasMany: [
{ model: 'package.Attendee', name: 'attendeeLabList', associationKey:'attendee_lab' },
{ model: 'package.Attendee', name: 'attendeeEmpList', associationKey:'attendee_emp' },
{ model: 'package.Document', name: 'document', associationKey:'document' },
]
#Izhaki helped me a lot. Thanx! Especially with the fiddle. I started there and begun with switching the code with my code piece by piece. Until I saw the model was the problem.
models should be defined like this: App.model.package.Attendee
I think it's sad that the framework doesn't show a significant error/warning if a model isn't recognised/doesn't excist/isn't supplied... But meh, it works now.

Categories