PDA

View Full Version : HasMany with XML reader: How to remove the filter?



schiffm
18 Sep 2013, 12:55 PM
I'm trying to load a complicated XML structure over which I have no control. The problem is that the subordinate record has no reference to the parent model. I've tried tweaking the HasMany association by defining/changing:

filterProperty
foreignKey
associatedModel
I'm missing something. Here is the simplified code (output in comments):



function toXmlDoc(xmlString) {
var parser,
xmlDoc;


if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString, "text/xml");
} else { // Internet Explorer
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(xmlString);
}


return xmlDoc;
}


var xml = toXmlDoc(
'<?xml version="1.0" encoding="utf-8"?> \
<rootElement> \
<data> \
<user id="user:1"> \
<userName>Bubbles</userName> \
<address> \
<city>Townsville</city> \
</address> \
<product id="product:1"> \
<name>This is a product</name> \
<description> \
<color>red</color> \
</description> \
</product> \
<product id="product:2"> \
<name>Another product</name> \
<description> \
<color>blue</color> \
</description> \
</product> \
</user> \
</data> \
</rootElement>'
);


Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{ name: 'userId', mapping: '@id' },
{ name: 'userName' },
{ name: 'city', mapping: 'address/city' }
],
associations: [
{ type: 'hasMany', model: 'Product', name: 'products', autoLoad: true }
],
proxy: {
type: 'memory',
data: xml,
reader: {
type: 'xml',
root: 'data',
record: 'user'
}
}
});


Ext.define('Product', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '@id' },
{ name: 'name', mapping: 'name' },
{ name: 'color', mapping: 'description/color' }
],
proxy: {
type: 'memory',
data: xml,
reader: {
type: 'xml',
root: 'user',
record: 'product'
}
}
});


Ext.onReady(function () {
User.load(1, {
success: function (user) {
console.log(user.get('userName') + ' of ' + user.get('city') + ', id = ' + user.get('userId')); // Bubbles of Townsville, id = user:1


console.log('Loaded ' + user.products().count() + ' products'); // Loaded 0 products

user.products().filters.items = [];
user.products().load();
console.log('Loaded ' + user.products().count() + ' products'); // Loaded 2 products
},
failure: function () {
console.log('Failed to load user');
}
});
});


Any suggestions would be appreciated.

ettavolt
18 Sep 2013, 10:47 PM
Try storeConfig:{remoteFilter:true,filterOnLoad:false} for your association config.

schiffm
19 Sep 2013, 6:05 AM
Try storeConfig:{remoteFilter:true,filterOnLoad:false} for your association config.

Thanks for your answer. Unfortunately, it didn't work. :( There was no difference in the output.

I also tried adding this to the User model: idProperty = 'userId' -- that gave me an error in Ext's Filter.js createFilterFn:


TypeError: filter.filterFn is undefined













isMatch = isMatch && filter.filterFn.call(filter.scope || filter, candidate);



Any other suggestions?

schiffm
23 Oct 2013, 10:57 AM
After working on this for several days, I finally found a solution that works, although it's not elegant.

This is what I added to my hasMany config:



storeConfig: {
listeners: {
beforeload: function (store, operation, eOpts) {
store.filters.clear();
operation.filters = [];
}
}
}


I hope this solution helps others, but I believe there is a bug in the framework. There seems to be no way to specify no filters, and with structured XML data like in my example, there should be no need to have an id property for the parent model in the associated data.

BTW, I'm using 4.2.1. I haven't looked to see if this problem is fixed by now.