PDA

View Full Version : Child nodes disappear on store reload



timbellomo
12 Apr 2012, 1:58 PM
I'm seeing some strange behavior in one of my stores, and I'm hoping this might make sense to someone else:

I have a store which loads via a json proxy/reader. The json it pulls in has some nested data, like so:


[
{
address: "123 Which Way",
apartment: "101",
city: "Nowhere",
comments: [
{
comment: "first comment",
date: "2012-04-12T14:23:44-07:00"
},
{
comment: "second comment",
date: "2012-04-12T14:23:44-07:00"
},
],
occupants: [
{
name: "Mr. A"
}
{
name: "Mr. A"
}
]
},
{...many more records...}
]


The store is tied to a list, which uses an XTemplate to display each location, as well as the occupants of the location in the list item -- and it all works wonderfully... the first time.

Subsequent store loads after the first load fail to populate the child nodes, so the "<tpl for='occupants'>" fails. Debugging shows that the json still passes the child nodes (the raw property shows them), but they disappear from the data property, and thus, from my list items.

In both cases, each store item has an "occupantsStore" and "commentsStore" property, but after the first load, the "occupants" and "comments" properties under "data" disappear.

Does anyone have any clue what might be going on?

Note 1: Occupants & Comments both have models that are associated with Locations.
Note 2: I did need to change some confidential details, so I've I made a slight syntax error in the json, I apologize. Trust me when I say it works on the first load (auto load or manual), but all subsequent store loads fail to populate the children).

Store def:


Ext.define('MCP.store.Locations', {
extend: 'Ext.data.Store',
config: {
model: 'MCP.model.Location',
//autoLoad: true,
proxy: {
type: 'ajax',
url : remoteServerUri + 'locations.json',
reader: {
type:'json',
},
},


sorters: [
{
property: 'address',
direction: 'DESC'
},
{
property: 'date',
direction: 'DESC',
root: 'comments'
}
],
}
});

mitchellsimoens
13 Apr 2012, 5:46 AM
When you say reload is this just doing store.load() or using the pullrefresh plugin?

timbellomo
13 Apr 2012, 5:52 AM
I'm just doing store.load().

I thought it might have had to do with autoload vs. manual, but it doesn't seem to matter. It's the first load that works, and all subsequent that do not.

timbellomo
18 Apr 2012, 12:36 PM
As a wild shot in the dark, I reconstructed my app using sencha sdk tools to confirm that I didn't have some wacky corrupt file problem. The issue persists: the first store load works properly, all subsequent store loads produce data that neglects the "comments" and "occupants" objects. The data items do contain "commentsStore" and "occupantsStore," so I know the json feed is coming across properly.

Is the reader the culprit here? Anybody else have any other ideas?

Bunchofstring
18 Apr 2012, 2:26 PM
Can you post MCP.model.Location and the associated models?

timbellomo
19 Apr 2012, 8:26 AM
I had been trying to obfuscate my code, but let's forget that now. Locations = Incidents, Occupants = Assignments, Comments = Comments.

MCP.model.Incident


Ext.define('MCP.model.Incident', {
extend: 'Ext.data.Model',

config: {
fields: [
{name: 'id', type: 'int' },
{name: 'incident_number', type: 'string' },
{name: 'response_date', type: 'date', dateFormat: 'c' },
{name: 'problem', type: 'string' },
{name: 'jurisdiction', type: 'string' },
{name: 'division', type: 'string' },
{name: 'battalion', type: 'string' },
{name: 'response_area', type: 'string' },
{name: 'response_plan', type: 'string' },
{name: 'incident_type', type: 'string' },
{name: 'priority_number', type: 'int' },
{name: 'priority_description', type: 'string' },
{name: 'premise_name', type: 'string' },
{name: 'preplan_reference', type: 'string'},
{name: 'location_name', type: 'string' },
{name: 'address', type: 'string' },
{name: 'city', type: 'string' },
{name: 'state', type: 'string' },
{name: 'postal_code', type: 'string' },
{name: 'county', type: 'string' },
{name: 'longitude', type: 'string' },
{name: 'latitude', type: 'string' },
{name: 'map_info', type: 'string' },
{name: 'cross_street', type: 'string' },
{name: 'call_is_active', type: 'string' }
],
hasMany:[
{model: 'MCP.model.Comment', name: 'comments'},
{model: 'MCP.model.Assignment', name: 'assignments'}
]
}
});


MCP.model.Comment


Ext.define('MCP.model.Comment', {
extend: 'Ext.data.Model',

config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'incident_id', type: 'int' },
{ name: 'performed_by', type: 'string' },
{ name: 'performed_on', type: 'date', dateFormat: 'c' },
{ name: 'comment', type: 'string' },
],
}
});


MCP.model.Assignment


Ext.define('MCP.model.Assignment', {
extend: 'Ext.data.Model',

config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'incident_id', type: 'int' },
{ name: 'unit_name', type: 'string' },
{ name: 'cleared_at', type: 'date',dateFormat: 'c' },
{ name: 'status_id', type: 'int' },
],

}
});


Additional information
The initial view is an Incident list, which uses an xtemplate to display the basic incident details, along with a list of assignments (i.e., units assigned to that incident). Upon selection of a list item, an Incident Detail panel is loaded, which (obviously) has more detail. But here's the weird thing: whereas the assignments and comments items disappear from the data objects in the Incidents store, if I inspect the record of the detail panel (which is simply set from the store on itemtap), it appropriately maps these values, and thus, the xtemplate continues to work on that panel (displaying the associated assignments and comments for the incident). Upon returning to the incident list though, the xtemplate fails.

I'm not sure that that totally made sense. Essentially:
Store -> data -> Item[0] -> data doesn't contain the assignments and comments objects, but DetailPanel -> Component -> _record -> _data does.

timbellomo
23 Apr 2012, 9:37 AM
Perhaps there's a way for me to reference the assignmentsStore and commentsStore, or rawData, in the xtemplate? While not quite a resolution for the odd behavior I'm seeing, it would be a workaround. Anyone know if this is somehow possible? Or is the Xtemplate scoped only to "data?"

timbellomo
24 Apr 2012, 3:27 PM
More information:

To clarify an earlier statement, it is not simply the second time that the store loads that the associations fail to propagate. If I have 5 Incidents, and reload the store, the associations for those incidents will fail to show. But if I reload again (and a new record has been added, bringing the total to 6), the oldest Incident *will* show it's associations properly! If 2 had been added between the refreshes, the oldest 2 Incidents will show their associations properly. That is, until I reload the store yet again, and the associations disappear.

Meanwhile, if I investigate the store records with


Ext.StoreManager.get('Active').data.items[0].assignments()

a class is returned containing all of the assignments. This makes some sense to me, as the detail view of each incident properly shows these assignments. I just can't understand why the list (which uses the same tpl snippet for assignment display) chokes on it.

I'm going to try different methods of association - perhaps something is slightly misconfigured. Although, if that were the case, I'd expect it to not work at all.

timbellomo
26 Apr 2012, 8:40 AM
By switching the display list from "Ext.dataview.List" to "Ext.dataview.DataView" the problem disappears. I can reload the store and the association objects will still populate.

This seems like a bug to me.

KeithBurns
17 May 2012, 4:58 AM
timbellomo,

I can confirm the the exact same behaviour as you describe.
I am using Sencha Architect Version 2.0.0 Build 442.
I posted the other day about not being able to sync the child nodes when using a model with hasmany association.

http://www.sencha.com/forum/showthread.php?205430-Cannot-sync-store-with-hasmany-association

I have been trying to narrow it down and checked to make sure the child node was there prior to syncing and I discovered the same problem as you and found your post.

My initial view is a list of jobs, where on selection a store is loaded with the nested json with a proxy/reader, like:


{jobdaydata:
[
{
id: "289",
MaintDay: "2012-05-17T00:00:00",
Notes: "Works completed",
jobdetails: [
{
id: "1",
jobday_id: "289",
EmployeeID: "2569",
Name: "John Deer"
},
{
id: "2",
jobday_id: "289",
EmployeeID: "2570",
Name: "James Burn"
},
],
{
id: "290",
MaintDay: "2012-05-18T00:00:00",
Notes: "Works completed",
jobdetails: [
{
id: "5",
jobday_id: "290",
EmployeeID: "2572",
Name: "Mary Alice"
},
{
id: "1",
jobday_id: "290",
EmployeeID: "2569",
Name: "John Deer"
}
]
}
]
}

Have trimmed so of the field for brevity.

The load of this store is dynamic to a different url depending on user selection, so setstore is called on the proxy as per CityBars example.


loadJobHoursList: function(sJobNumber, sYear, sMonth) {
var me = this;
var sUrlnew = '/Maint/data/' + sYear + '/' + sMonth + '/' + sJobNumber + '.json';

me.getJobHours(sUrlnew, function(store) {
me.getJobDetailList().setStore(store);
jobRecordCount.value = store.getCount();
});
This store is tied to a list with the MaintDay values displayed.

Selection of MaintDay loads a details sheet which has the child elements on it. This all works great, but have the same thing where the child node is dropped on the second load.
See picture of inspector;

I can also confirm that if I change from List to DataView the second and subsequent loads have the child nodes.
I have not checked yet if I can sync using a Dataview

Will check this and post.

I am in the dark also about what is happening, but hopefully this helps.

Thanks

KeithBurns
27 May 2012, 6:53 PM
Can any one help with this or confirm if it is a bug?

eric.teong
6 Jun 2012, 2:12 AM
I'm also facing this same issue. After tried for few days, I found that if I called yourStore.removeAll(); before calling the yourStore.load(). This will able to make the list to render the child nodes out.

shobbyc
29 Apr 2013, 3:39 AM
hello,
I am generating a nested list using json, but problem is that,
I am able to display Parent Elements, but not child elements. It is may be because I am missing somthing.

Here is my json:

{
"categoryHierarchyElement": [{
"childCategories": {
"category": [{
"id": "subCatId11",
"displayName": "For Him"
}, {
"id": "subCatId12",
"displayName": "For Her"
}, {
"id": "subCatId13",
"displayName": "Gift Certificates"
}
]
},
"categoryId": "topCatId1",
"displayName": "Gift Ideas"
},


{
"childCategories": {
"category": [{
"id": "subCatId21",
"displayName": "Shirts"
}, {
"id": "subCatId22",
"displayName": "Pants"
}, {
"id": "subCatId23",
"displayName": "Dresses"
}, {
"id": "subCatId24",
"displayName": "Skirts"
}, {
"id": "subCatId25",
"displayName": "Shorts"
}, {
"id": "subCatId26",
"displayName": "Jackets"
}, {
"id": "subCatId27",
"displayName": "Accessories"
}
]
},
"categoryId": "topCatId2",
"displayName": "Women's Apparel"
},


{
"childCategories": {
"category": [{
"id": "subCatId31",
"displayName": "Women's Shoes"
}, {
"id": "subCatId32",
"displayName": "Men's Shoes"
}
]
},
"categoryId": "topCatId3",
"displayName": "Footwear"
},


{
"childCategories": {
"category": [{
"id": "subCatId41",
"displayName": "Tables"
}, {
"id": "subCatId42",
"displayName": "Seating"
}, {
"id": "subCatId43",
"displayName": "Storage & Display"
}
]
},


"categoryId": "topCatId4",
"displayName": "Home Store"
}, {
"childCategories": {
"category": [{
"id": "subCatId51",
"displayName": "Towels and Linens"
}
]
},




"categoryId": "topCatId5",
"displayName": "Bed & Bath"
}, {
"childCategories": {
"category": [{
"id": "subCatId61",
"displayName": "Clocks"
}, {
"id": "subCatId62",
"displayName": "Radios"
}, {
"id": "subCatId63",
"displayName": "Cushions and Pillows"
}, {
"id": "subCatId64",
"displayName": "Glassware"
}, {
"id": "subCatId65",
"displayName": "Lamps and Lighting"
}, {
"id": "subCatId66",
"displayName": "Miscellaneous"
}
]
},


"categoryId": "topCatId6",
"displayName": "Home Accessories"
}
]
}
here is my Main.js:

Ext.define("test.view.Main", {
extend: 'Ext.tab.Panel',
id:'tabpnl',
requires: ['Ext.TitleBar','Ext.field.Select','Ext.field.Search'],


config: {
tabBarPosition: 'bottom',
//text:'Mobile Cube',
styleHtmlContent: true,
items:[ {
xtype: 'nestedlist',
title: 'Store',
iconCls: 'star',
displayField: 'displayName',


store: {
type: 'tree',


fields: ['displayName',
],


root: {
leaf: false
},


proxy: {
type: 'ajax',
url: 'http://localhost:8080/rest/catalog/category/hierarchy',
reader: {
type: 'json',
rootProperty: 'categoryHierarchyElement'
}
}
},
}]

}
});

here is my app.js:

Ext.application({
name: 'test',


requires: [
'Ext.MessageBox'
],


views: ['Main'],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon@2x.png',
'144': 'resources/icons/Icon~ipad@2x.png'
},


isIconPrecomposed: true,


startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},


launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();


// Initialize the main view
Ext.Viewport.add(Ext.create('test.view.Main'));
},


onUpdated: function() {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function(buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});


Please help me, i have to display items like For Him,For Her etc.

Thanks..
shobby