PDA

View Full Version : Problem with JSON



pcr
17 Nov 2010, 9:54 AM
Hi

I trie to start using Sencha-touch. I took kitchensink example and trie to modify it for my app.
In kitchensink I tried to replace sink.Structure (inside code in index.js) into a structure retrieved by a remote ajax JSON.
Not a too difficult move, right. I build a backendPHPscript that generate the JSON. All works almost fine. The menu works like expected. There is one thing wrong. The selected page does not show. I debugged in Safari and saw the difference between sink.Structure and my JSON.

In sink.Structure I read:



sink.Structure = [{
text: 'User Interface',
cls: 'launchscreen',
items: [{
text: 'Buttons',
card: demos.Buttons,
source: 'src/demos/buttons.js',
leaf: true
},
{
text: 'Forms',
card: demos.Forms,
source: 'src/demos/forms.js',
leaf: true
},
{
text: 'List',
card: demos.List,
source: 'src/demos/list.js',
leaf: true
},
{
text: 'Nested List',
card: demos.NestedList,
source: 'src/demos/nestedlist.js',
leaf: true
},
{
text: 'Icons',
card: demos.Icons,
source: 'src/demos/icons.js',
leaf: true
},
{
text: 'Toolbars',
card: demos.Toolbars,
source: 'src/demos/toolbars.js',
leaf: true
},
{
text: 'Carousel',
card: demos.Carousel,
source: 'src/demos/carousel.js',
leaf: true
},
{
text: 'Tabs',
card: demos.Tabs,
source: 'src/demos/tabs.js',
leaf: true
},
{
text: 'Bottom Tabs',
card: demos.BottomTabs,
source: 'src/demos/bottomtabs.js',
leaf: true
},
/*{
text: 'Picker',
card: demos.Picker,
source: 'src/demos/picker.js',
leaf: true
},*/
{
text: 'Map',
card: demos.Map,
source: 'src/demos/map.js',
leaf: true
},
{
text: 'Overlays',
card: demos.SheetsOverlays,
source: 'src/demos/sheets_overlays.js',
leaf: true
}]
},
{
text: 'Animations',
source: 'src/demos/animations.js',
card: Ext.is.Phone ? false : demos.Animations,
items: [{
text: 'Slide',
card: demos.Animations.slide,
preventHide: true,
cardSwitchAnimation: 'slide',
leaf: true
},
{
text: 'Slide (cover)',
card: demos.Animations.slidecover,
preventHide: true,
cardSwitchAnimation: {
type: 'slide',
cover: true
},
leaf: true
},
{
text: 'Slide (reveal)',
card: demos.Animations.slidereveal,
preventHide: true,
cardSwitchAnimation: {
type: 'slide',
reveal: true
},
leaf: true
},
{
text: 'Pop',
card: demos.Animations.pop,
preventHide: true,
cardSwitchAnimation: {
type: 'pop',
scaleOnExit: true
},
leaf: true
},
{
text: 'Fade',
card: demos.Animations.fade,
preventHide: true,
cardSwitchAnimation: {
type: 'fade',
duration: 600
},
leaf: true
},
{
text: 'Flip',
card: demos.Animations.flip,
preventHide: true,
cardSwitchAnimation: {
type: 'flip',
duration: 400
},
leaf: true
},
{
text: 'Cube',
card: demos.Animations.cube,
preventHide: true,
cardSwitchAnimation: {
type: 'cube',
duration: 400
},
leaf: true
}]
},
{
text: 'Touch Events',
card: demos.Touch,
source: 'src/demos/touch.js',
leaf: true
},
{
text: 'Data',
items: [
{
text: 'Nested Loading',
card: demos.Data.nestedLoading,
source: 'src/demos/data/nestedLoading.js',
leaf: true
},
{
text: 'JSON P',
card: demos.Data.jsonp,
source: 'src/demos/data/jsonp.js',
leaf: true
},
{
text: 'YQL',
card: demos.Data.yql,
source: 'src/demos/data/yql.js',
leaf: true
},
{
text: 'AJAX',
card: demos.Data.ajax,
source: 'src/demos/data/ajax.js',
leaf: true
}
]
},
{
text: 'Media',
items: [{
text: 'Video',
card: demos.Video,
source: 'src/demos/video.js',
leaf: true
}, {
text: 'Audio',
card: demos.Audio,
source: 'src/demos/audio.js',
leaf: true
}]
}
];

My JSON is :



{
"items": [{
"text": "Archief",
"iconCls": "ar-icon-grid",
"items": [{
"text": "Account EXT Account EXT",
"source": "src/demos/buttons.js",
"card": "demos.Buttons",
"preventHide": true,
"cardSwitchAnimation": {
"type": "fade",
"duration": 600
},
"textH": "Account EXT",
"textO": "Account EXT",
"HnaamId": "1",
"OnaamId": "1",
"profielid": "846",
"module": "Archief",
"moduleid": "51",
"hwaarde": "1",
"owaarde": "1",
"C": "0",
"R": "0",
"U": "0",
"D": "0",
"Confirm": "off",
"Gridautorefresh": 0,
"GridSize": 15,
"iconCls": "ar-icon-grid",
"leaf": true
}]},{
"text": "Processen",
"iconCls": "proc-icon-grid",
"items": [{
"text": "Account EXT Account EXT",
"source": "src/demos/buttons.js",
"card": "demos.Animations.pop",
"preventHide": true,
"cardSwitchAnimation": {
"type": "fade",
"duration": 600
},
"textH": "Account EXT",
"textO": "Account EXT",
"HnaamId": "1",
"OnaamId": "1",
"profielid": "729",
"module": "Processen",
"moduleid": "41",
"hwaarde": "1",
"owaarde": "1",
"C": "1",
"R": "1",
"U": "0",
"D": "0",
"Confirm": "off",
"Gridautorefresh": 0,
"GridSize": 15,
"iconCls": "proc-icon-grid",
"leaf": true
}
]
}]}
The difference is:

In sink.Structure
"card": demos.Buttons ( no double-quotes around demos.Buttons)

In JSON
"card": "demos.Buttons" ( double-quotes around demos.Buttons)

If I trie without the doublequotes around demos.buttons Safari shows an error 'Cannot parse JSON'

Can somebody help me to solve this????

blessan
17 Nov 2010, 10:33 PM
i guess the quotes are causing the trouble. try to use a eval method on it. might work.

taka_2
18 Nov 2010, 12:33 AM
What version of Sencha Touch are you using?
Your JSON is working correctly in my example code using Sencha Touch 1.0.
My example code is the following.


Ext.setup({
onReady : function() {
// store with data
Ext.regModel('ListItem', {
fields: [{name: 'text', type: 'string'}]
});
var store = new Ext.data.TreeStore({
model: 'ListItem',
proxy: {
type: 'ajax',
url: '/Problem_with_JSON/index.json',
reader: {
type: 'tree',
root: 'items'
}
}
});
var nestedList = new Ext.NestedList({
fullscreen: true,
title: 'NestedList',
displayField: 'text',
store: store
});
}
});

pcr
18 Nov 2010, 1:57 AM
Hi I know what happend. The "card" : demos.Buttons is used to switch to the component demos.Buttons on menuclick. With JSON you cannot define references to objects. Only nummers bool or strings are allowed. So i made workaround by compare the string and do proper action (switch to the compont ).

pcr
18 Nov 2010, 2:02 AM
I use Sencha- Touch 1.0

I tested my JSON with JSLint so I know it is correct. I know now you cannot simple replace the inline component sink.Structure with external JSON. See former depot.

Is there another way to build JSON for a TreeStore with a pair that defines the clickhandler?

taka_2
18 Nov 2010, 10:46 PM
I understood what the problem.
As a result the following corrections, and it works.
I think another better way is exists because eval is heavy function.

examples/kitchensink/src/index.js Line 153 to 156:


if (card) {
this.setActiveItem(card, anim || 'slide');
this.currentCard = card;
}

Corrected:


var objCard = eval(card);
if (card) {
this.setActiveItem(objCard, anim || 'slide');
this.currentCard = objCard;
}

pcr
19 Nov 2010, 2:28 AM
Ok. the eval option works. You'r write about eval. I dont want to use it. What do you mean by 'better way is exists'???

taka_2
19 Nov 2010, 3:33 AM
For example, demos.Buttons is defined as Global Object in buttons.js.
demos.Buttons is available to access as window["demos"]["Buttons"].

Need to convert "demos.Buttons" string to ["demos"]["Buttons"] array.
But I couldn't find those utility method. so I defined it "getGlobalObject".



var getGlobalObject = function (objName)
{
var objNameSplitted = objName.split('.');

var i;
var currentObj = window;
for(i=0; i<objNameSplitted.length; i++)
{
currentObj = currentObj[objNameSplitted[i]];
}

return currentObj;
}

var objCard = getGlobalObject(card);
if (card) {
this.setActiveItem(objCard, anim || 'slide');
this.currentCard = objCard;
}

blessan
19 Nov 2010, 3:54 AM
is this really better than using eval?

pcr
20 Nov 2010, 12:37 AM
I dont think eval is worse for security. I use ExtJS as long as ExtJS exists. I used to build codeblocks (front-, and backend) to most ExtJS widgets like Trees, Grids, Layouts, FileUpload etc. Building applications by putting these blocks together is easier.

What I am looking for is an alternative for a navigationtree concept in Sencha-Touch. The one in kitchensink is based on an inline object. Not on JSON. For now the eval solution works fine. If appreciate if somebody has a better solution.