views:

6121

answers:

3

I'm building a listing/grid control in a Flex application and using it in a .NET web application. To make a really long story short I am getting XML from a webservice of serialized objects. I have a page limit of how many things can be on a page. I've taken a data grid and made it page, sort across pages, and handle some basic filtering.

In regards to paging I'm using a Dictionary keyed on the page and storing the XML for that page. This way whenever a user comes back to a page that I've saved into this dictionary I can grab the XML from local memory instead of hitting the webservice. Basically, I'm caching the data retrieved from each call to the webservice for a page of data.

There are several things that can expire my cache. Filtering and sorting are the main reason. However, a user may edit a row of data in the grid by opening an editor. The data they edit could cause the data displayed in the row to be stale. I could easily go to the webservice and get the whole page of data, but since the page size is set at runtime I could be looking at a large amount of records to retrieve.

So let me now get to the heart of the issue that I am experiencing. In order to prevent getting the whole page of data back I make a call to the webservice asking for the completely updated record (the editor handles saving its data).

Since I'm using custom objects I need to serialize them on the server to XML (this is handled already for other portions of our software). All data is handled through XML in e4x. The cache in the Dictionary is stored as an XMLList.

Now let me show you my code...

var idOfReplacee:String = this._WebService.GetSingleModelXml.lastResult.*[0].*[0].@Id;
var xmlToReplace:XMLList = this._DataPages[this._Options.PageIndex].Data.(@Id == idOfReplacee);

if(xmlToReplace.length() > 0)
{
    delete (this._DataPages[this._Options.PageIndex].Data.(@Id == idOfReplacee)[0]);
    this._DataPages[this._Options.PageIndex].Data += this._WebService.GetSingleModelXml.lastResult.*[0].*[0];
}

Basically, I get the id of the node I want to replace. Then I find it in the cache's Data property (XMLList). I make sure it exists since the filter on the second line returns the XMLList.

The problem I have is with the delete line. I cannot make that line delete that node from the list. The line following the delete line works. I've added the node to the list.

How do I replace or delete that node (meaning the node that I find from the filter statement out of the .Data property of the cache)???

Hopefully the underscores for all of my variables do not stay escaped when this is posted! otherwise this.&#95 == this._

A: 

I don't immediately see the problem, so I can only venture a guess. The delete line that you've got is looking for the first item at the top level of the list which has an attribute "Id" with a value equal to idOfReplacee. Ensure that you don't need to dig deeper into the XML structure to find that matching id.

Try this instead:

delete (this._DataPages[this._Options.PageIndex].Data..(@Id == idOfReplacee)[0]);

(Notice the extra '.' after Data). You could more easily debug this by setting a breakpoint on the second line of the code you posted, and ensure that the XMLList looks like you expect.

Matt Dillard
A: 

Perhaps you could use replace instead?

var oldNode : XML = this._DataPages[this._Options.PageIndex].Data.(@Id == idOfReplacee)[0];
var newNode : XML = this._WebService.GetSingleModelXml.lastResult.*[0].*[0];    

oldNode.parent.replace(oldNode, newNode);
Theo
+2  A: 

Thanks for the answers guys.

@Theo: I tried the replace several different ways. For some reason it would never error, but never update the list.

@Matt: I figured out a solution. The issue wasn't coming from what you suggested, but from how the delete works with Lists (at least how I have it in this instance).

The Data property of the _DataPages dictionary object is list of the definition nodes (was arrived at by a previous filtering of another XML document).

<Models>
     <Definition Id='1' />
     <Definition Id='2' />
</Models>

I ended up doing this little deal:

//gets the index of the node to replace from the same filter
var childIndex:int = (this._DataPages[this._Options.PageIndex].Data.(@Id == idOfReplacee)[0]).childIndex();
//deletes the node from the list
delete this._DataPages[this._Options.PageIndex].Data[childIndex];
//appends the new node from the webservice to the list
this._DataPages[this._Options.PageIndex].Data += this._WebService.GetSingleModelXml.lastResult.*[0].*[0];

So basically I had to get the index of the node in the XMLList that is the Data property. From there I could use the delete keyword to remove it from the list. The += adds my new node to the list.

I'm so used to using the ActiveX or Mozilla XmlDocument stuff where you call "SelectSingleNode" and then use "replaceChild" to do this kind of stuff. Oh well, at least this is in some forum where someone else can find it. I do not know the procedure for what happens when I answer my own question. Perhaps this insight will help someone else come along and help answer the question better!

Mike G.

Mike G