Read Previous Example First!
In this example, we’ll improve our ExtJS 4 model to include an “association” that it will read from XML produced by AJAX call to ASP.NET. Most common association is one to many, for example: your Client can place multiple Orders. An ExtJS 4 data store and model can accommodate this.
The new XML data packet will look like this; notice hiddenAttributes:
<?xml version="1.0" encoding="utf-8"?> <matches> <match> <id>0</id> <name>Number 0</name> <hiddenAttributes> <attr> <name>hidden1</name> <value>val1</value> </attr> <attr> <name>hidden2</name> <value>val2</value> </attr> </hiddenAttributes> </match> <match><id>1</id><name>Number 1</name></match> ... </matches> |
We will add an associations attribute to our model. Also, we introduce a new model, for the “many” portion of one-to-many relationship:
// Model Ext.define('MyOrg.model.SearchResult', { extend: 'Ext.data.Model' , fields: ['id','name'] , associations: [{ // Hidden Attributes type: 'hasMany' , model: 'MyOrg.model.SearchResult_HiddenAttribute' , associationKey: 'hiddenAttributes' // inner XML node name , name: 'hiddenAttributes' // Name of the parent store's record's method; if not // specified, it will be lower-cased model with "s" at end , reader: { type: 'xml', record: 'attr' } }] // eo associations }); // Model of hidden attributes Ext.define('MyOrg.model.SearchResult_HiddenAttribute', { extend: 'Ext.data.Model', fields: ['name','value'] }); |
No changes to ExtJS Store are needed! Model takes care of it all! You will now have association data available in the ExtJS 4 data store:
store.data.each(function(item,index,length) { // No popup if there are no popup attributes var hiddenAttriubtes = item.hiddenAttriubtes(); if ( hiddenAttriubtes.getCount() == 0 ) return; // Build popup HTML var popupHtml = '<table>'; hiddenAttriubtes.data.each(function(hiddenAttriubte){ popupHtml += '<tr><td>' + Ext.htmlEncode(hiddenAttriubte.data.name) + '</td><td>' + Ext.htmlEncode(hiddenAttriubte.data.value) + '</td></tr>' }); popupHtml += '</table>'; Ext.Msg.alert('Hidden Attributes', popupHtml); }); |
Here’s the corresponding changes to our XML generation script in ASP.NET:
/// <summary> /// Returns XML matches/match[id,name] /// </summary> /// <param name="query">Search query</param> [WebMethod(EnableSession = true)] [ScriptMethod(ResponseFormat=ResponseFormat.Xml,UseHttpGet = false,XmlSerializeString = false)] public static XmlDocument Search( string query ) { XmlDocument doc = new XmlDocument(); using (XmlWriter writer = doc.CreateNavigator().AppendChild()) { writer.WriteStartDocument(); writer.WriteStartElement("matches"); // Some postback JSON data { LDAPFilter: '...', MoreData: '...' } Dictionary<string,object> JSONData = new Dictionary<string,object>(); JSONData["LDAPFilter"] = "(&(sAMAccountName=*))"; JSONData["MoreData"] = "Another var could be DateTime, etc."; string XMLData = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(JSONData); writer.WriteElementString("jsonData", XMLData); for (int i = 0; i < 100; i++) { writer.WriteStartElement("match"); writer.WriteElementString("id", i); writer.WriteElementString("name", "Number " + i); writer.WriteStartElement("hiddenAttributes"); writer.WriteStartElement("attr"); writer.WriteElementString("name", "Order ID"); writer.WriteElementString("value", "1"); writer.WriteEndElement(); writer.WriteStartElement("attr"); writer.WriteElementString("name", "Order Name" ); writer.WriteElementString("value", "First Order"); writer.WriteEndElement(); writer.WriteEndElement(); // eo hiddenAttributes writer.WriteEndElement(); // eo match } writer.WriteEndElement(); // eo matches writer.WriteEndDocument(); } return doc; } |