PDA

View Full Version : MemoryProxy: how to put a XML doc into a store?



DennisFLS
5 Jun 2012, 5:00 AM
Hi there,

I'm currently trying to load XML data (originating from a web service) into a XmlStore via a MemoryProxy. For testing purposes, I want to display the data in a grid panel. The problem: the data doesn't get displayed (for me, it does look like the data isn't even correctly loaded; the "data"-property in Firebug is pretty empty).

I've created a jsfiddle to demonstrate: http://jsfiddle.net/HqfmJ/1/

Basically, it goes like this:


var xmlString = '<?xml version="1.0" encoding="utf-8"?>' +
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
'<soap:Body>' +
'<Response>' +
' <Result>' +
' <Record>' +
' <Value>1</Value>' +
' <Name>foo</Value>' +
' </Record>' +
' <Record>' +
' <Value>2</Value>' +
' <Name>blah</Value>' +
' </Record>' +
' <Record>' +
' <Value>3</Value>' +
' <Name>foobar</Value>' +
' </Record>' +
' </Result>' +
' </Response>' +
' </soap:Body>' +
'</soap:Envelope>';

/* convert string to xml document (IE currently not supported) to simulate response XML (coming from Ext.Ajax.request's success() function */
var parser = new DOMParser();
var xmlDoc = parser.parseFromString( xmlString, 'text/xml' );

/* create model */
Ext.define( 'Model', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Value', mapping: 'Value' },
{ name: 'Name', mapping: 'Name' }
],
idProperty: 'Value'
});

/* create store */
var store = new Ext.data.XmlStore({
autoLoad: true,
model: 'Model',
data: xmlDoc,
proxy: {
type: 'memory',
reader: {
type: 'xml',
root: 'Record'
}
},
load: function( store, records, success) {
console.log( 'store', store );
console.log( 'records', records );
console.log( 'success', success );
}
});

/* create application and grid */
Ext.application({
name: 'Test',

launch: function() {
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
width: '300',
items: [
{
xtype: 'grid',
store: store,
title: 'Test',
width: '100%',
columns: [
{
header: 'The Value',
dataIndex: 'Value'
},
{
header: 'The Name',
dataIndex: 'Name'
}
]
}
]
});
}

});



The load()-function gets called, but all the parameters are "undefined". Above all, I feel like some properties aren't even needed where I put them. Do I miss something obvious?

Thanks in advance!

droessner
5 Jun 2012, 5:40 PM
The first issue is that your XML is incorrect. Your name tags do not have the correct end tags. Make sure these match. You'll also need to put the load function within the listeners object.

This should do it:


var xmlString = '<?xml version="1.0" encoding="utf-8"?>' + '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
'<soap:Body>' +
'<Response>' +
' <Result>' +
' <Record>' +
' <Value>1</Value>' +
' <Name>foo</Name>' +
' </Record>' +
' <Record>' +
' <Value>2</Value>' +
' <Name>blah</Name>' +
' </Record>' +
' <Record>' +
' <Value>3</Value>' +
' <Name>foobar</Name>' +
' </Record>' +
' </Result>' +
' </Response>' +
' </soap:Body>' +
'</soap:Envelope>';


/* convert string to xml document (IE currently not supported) to simulate response XML (coming from Ext.Ajax.request's success() function */
var parser = new DOMParser();
var xmlDoc = parser.parseFromString( xmlString, 'text/xml' );


/* create model */
Ext.define( 'Model', {
extend: 'Ext.data.Model',
fields: [
{ name: 'Value', mapping: 'Value' },
{ name: 'Name', mapping: 'Name' }
],
idProperty: 'Value'
});


/* create store */
var store = new Ext.data.XmlStore({
autoLoad: true,
model: 'Model',
data: xmlDoc,
proxy: {
type: 'memory',
reader: {
type: 'xml',
root: 'Record'
}
},
listeners: {
load: function( store, records, success) {
console.log( 'records', records );
console.log( 'success', success );
}
}
});


/* create application and grid */
Ext.application({
name: 'Test',

launch: function() {
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
width: '300',
items: [
{
xtype: 'grid',
store: store,
title: 'Test',
width: '100%',
columns: [
{
header: 'The Value',
dataIndex: 'Value'
},
{
header: 'The Name',
dataIndex: 'Name'
}
]
}
]
});
}


});

DennisFLS
5 Jun 2012, 11:07 PM
Thanks for your help - running a few tests by myself after posting, I noticed that my XML wasn't even valid, but I haven't had the time to fix it.

Nonetheless, your code doesn't work either, because we both missed an (appearently) important property of the reader object: "record". "root" isn't even needed. Grraaaagh, this was messing with my head...

So, here's the code that works:


var xmlString = '<?xml version="1.0" encoding="utf-8"?>' + '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
'<soap:Body>' +
'<Response>' +
' <Result>' +
' <Record>' +
' <Value>1</Value>' +
' <Name>foo</Name>' +
' </Record>' +
' <Record>' +
' <Value>2</Value>' +
' <Name>blah</Name>' +
' </Record>' +
' <Record>' +
' <Value>3</Value>' +
' <Name>foobar</Name>' +
' </Record>' +
' </Result>' +
' </Response>' +
' </soap:Body>' +
'</soap:Envelope>';

/* convert string to xml document (IE currently not supported) to simulate response XML (coming from Ext.Ajax.request's success() function */
var parser = new DOMParser();
var xmlDoc = parser.parseFromString( xmlString, 'text/xml' );

/* create model */
Ext.define( 'Model', {
extend: 'Ext.data.Model',
fields: [
// type description isn't really needed
{ name: 'Value', mapping: 'Value' , type: 'int' },
{ name: 'Name', mapping: 'Name' , type: 'string' }
],
idProperty: 'Value'
});


/* create store */
var store = new Ext.data.XmlStore({
autoLoad: true,
model: 'Model',
data: xmlDoc,
proxy: {
type: 'memory',
reader: {
type: 'xml',
// root: 'Record' -> not needed
record: 'Record' // here we go
}
},
listeners: {
load: function( store, records, success) {
console.log( 'store', store );
console.log( 'records', records );
console.log( 'success', success );
console.log( 'store.getCount(): ', store.getCount() );
}
}
});


/* create application and grid */
Ext.application({
name: 'Test',

launch: function() {
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
width: '300',
items: [
{
xtype: 'grid',
store: store,
title: 'Test',
width: '100%',
columns: [
{
header: 'The Value',
dataIndex: 'Value'
},
{
header: 'The Name',
dataIndex: 'Name'
}
]
}
]
});
}
});

And the updated fiddle: http://jsfiddle.net/HqfmJ/5/

droessner, I up-voted your post but marked mine as the best answer. I hope you agree to that.