在E4X中删除/替换节点(AS3 - Flex)

时间:2008-08-14 12:27:00

标签: flex actionscript-3 e4x

我正在Flex应用程序中构建列表/网格控件,并在.NET Web应用程序中使用它。总而言之,我从序列化对象的Web服务中获取XML。我有一个页面限制,页面上可以有多少东西。我已经采用了数据网格并将其设置为页面,对页面进行排序,并处理一些基本过滤。

关于分页我正在使用键在页面上的字典并存储该页面的XML。这样,每当用户返回到我已保存到此字典中的页面时,我都可以从本地内存中获取XML而不是访问Web服务。基本上,我正在将从每次调用检索到的数据缓存到Web服务中以获取数据页。

有几件事可以使我的缓存失效。过滤和排序是主要原因。但是,用户可以通过打开编辑器来编辑网格中的一行数据。他们编辑的数据可能导致行中显示的数据过时。我可以轻松地访问web服务并获取整个页面的数据,但由于页面大小是在运行时设置的,因此我可以查看大量要检索的记录。

所以现在让我谈谈我遇到的问题的核心。为了防止获取整个数据页面,我调用了webservice,询问完整更新的记录(编辑器处理保存其数据)。

由于我正在使用自定义对象,我需要在服务器上将它们序列化为XML(这已经针对我们软件的其他部分进行了处理)。所有数据都通过e4x中的XML处理。 Dictionary中的缓存存储为XMLList。

现在让我告诉你我的代码......

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];
}

基本上,我得到了我要替换的节点的id。然后我在缓存的Data属性(XMLList)中找到它。我确保它存在,因为第二行上的过滤器返回XMLList

我遇到的问题是删除行。我无法使该行从列表中删除该节点。删除行后面的行有效。我已将节点添加到列表中。

如何替换或删除该节点(意味着我从缓存的.Data属性中的filter语句中找到的节点)???

希望所有变量的下划线在发布时不会保留转义!否则this.&#95 == this ._

4 个答案:

答案 0 :(得分:2)

感谢你们的答案。

@Theo: 我尝试了几种不同的替换方式。出于某种原因,它永远不会出错,但永远不会更新列表。

@马特: 我想出了一个解决方案。问题不是来自你的建议,而是来自删除如何与列表一起使用(至少我在这个例子中如何使用它)。

_DataPages字典对象的Data属性是定义节点的列表(通过先前对另一个XML文档的过滤得到)。

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

我最终做了这个小小的交易:

//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];

所以基本上我必须得到XMLList中作为Data属性的节点的索引。从那里我可以使用delete关键字将其从列表中删除。 + =将我的新节点添加到列表中。

我已经习惯使用ActiveX或Mozilla XmlDocument来调用“SelectSingleNode”,然后使用“replaceChild”来做这种事情。哦,至少这是在某个论坛,其他人可以找到它。我不知道回答我自己的问题时会发生什么的程序。也许这种见解会帮助其他人出现并帮助更好地回答这个问题!

答案 1 :(得分:1)

也许您可以使用replace代替?

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);

答案 2 :(得分:1)

我知道这是一个令人难以置信的老问题,但我不知道(我认为是)这个问题最简单的解决方案。

Theo在这里有正确的方向,但是使用替换方式存在许多错误(事实上,E4X中的所有内容都是函数)。

我相信这会解决问题:

oldNode.parent().replace(oldNode.childIndex(), newNode);

replace()可以在第一个参数中使用多种不同的类型,但AFAIK,XML对象不是其中之一。

答案 3 :(得分:0)

我没有立即看到问题,所以我只能猜测。您获得的delete行正在查找列表顶级的第一项,其中属性“Id”的值等于idOfReplacee。确保您不需要深入研究XML结构以找到匹配的id。

请改为尝试:

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

(注意Data之后的额外'。'。您可以通过在发布的代码的第二行设置断点来更轻松地调试它,并确保XMLList看起来像您期望的那样。