使用e4x在Flex中编辑XML

时间:2008-09-15 14:05:47

标签: javascript flex e4x

在Flex中,我有一个xml文档,如下所示:

var xml:XML = <root><node>value1</node><node>value2</node><node>value3</node></root>

在运行时,我想为root下的每个节点创建一个TextInput控件,并将值绑定到XML中的值。据我所知,我不能在运行时使用BindingUtils绑定到e4x节点(请告诉我,如果我错在这里!),所以我试图手工完成这个:

for each (var node:XML in xml.node)
{
    var textInput:TextInput = new TextInput();
    var handler:Function = function(event:Event):void 
    {
        node.setChildren(event.target.text);
    };
    textInput.text = node.text();
    textInput.addEventListener(Event.CHANGE, handler);
    this.addChild(pileHeightEditor);
}

我的问题是,当用户编辑其中一个TextInput时,被分配的节点始终是for循环中遇到的最后一个节点。我习惯于使用C#中的这种模式,每次创建一个匿名函数时,都会使用所使用值的值的“快照”,因此每个处理函数中的“node”会有所不同。

如何“处理”要在处理程序中使用的节点的当前值的“快照”?或者我应该在Flex中使用不同的模式吗?

2 个答案:

答案 0 :(得分:2)

不幸的是,ActionScript中的函数闭包工作很奇怪/很差。变量只有在超出范围时才会获得“快照”。不幸的是,变量是函数作用域,而不是块作用域。所以它最终不会像你想要的那样工作。

您可以创建一个字典来映射 TextInput - &gt;节点,或者您可以将节点存储在TextInput's数据属性中。

我希望你所描述的内容能够正常工作,因为它是一种简单/有效的表达方式。

答案 1 :(得分:2)

闭包只捕获变量的引用,而不是当前值。由于局部变量是函数范围的(不是块范围的),因此每次迭代循环都会创建一个闭包,捕获对同一变量的引用。

您可以将TextInput创建代码提取到一个单独的函数中,这将为您提供一个单独的变量实例来捕获闭包。像这样:

for each (var node:XML in xml.node)
{
    var textInput:TextInput = createTextInput(node);
    this.addChild(pileHeightEditor);
}
... 

private function createTextInput(node:XML) : TextInput {
    var textInput:TextInput = new TextInput();
    var handler:Function = function(event:Event):void 
    {
        node.setChildren(event.target.text);
    };
    textInput.text = node.text();
    textInput.addEventListener(Event.CHANGE, handler);
    return textInput;
}