使用e4x在Flex中编辑XML
时间:2020-03-05 18:53:34 来源:igfitidea点击:
在Flex中,我有一个如下的xml文档:
var xml:XML = <root><node>value1</node><node>value2</node><node>value3</node></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); }
我的问题是,当用户编辑TextInputs之一时,被分配给该节点的节点始终是for循环中遇到的最后一个节点。我习惯于C#的这种模式,每次创建一个匿名函数时,都会使用所使用值的"快照",因此每个处理程序函数中的"节点"将有所不同。
如何为处理程序中使用的节点的当前值"拍摄快照"?还是我应该在Flex中使用其他模式?
解决方案
回答
不幸的是,在Actionscript中,函数闭包工作很奇怪/很差。当变量超出范围时,它们只会获得"快照"。不幸的是,变量是函数范围的,而不是块范围的。因此,它不会像我们想要的那样工作。
我们可以创建一个字典来从TextInput->节点进行映射,也可以将该节点存储在TextInput的data属性中。
我希望我们所描述的内容能够正确运行,因为这是一种轻松/有效的表达方式。
回答
闭包仅捕获对变量的引用,而不捕获其当前值。由于局部变量是函数作用域的(而不是块作用域的),因此循环中的每次迭代都会创建一个闭包,该闭包捕获对同一变量的引用。
我们可以将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; }