Pregunta

En Flex, tengo un documento xml como el siguiente:

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

En tiempo de ejecución, quiero crear un control TextInput para cada nodo en la raíz y tener los valores vinculados a los valores en el XML.Hasta donde puedo decir, no puedo usar BindingUtils para vincularme a nodos e4x en tiempo de ejecución (¡dígame si me equivoco aquí!), así que estoy tratando de hacer esto a mano:

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

Mi problema es que cuando el usuario edita uno de los TextInputs, el nodo al que se asigna es siempre el último que se encuentra en el bucle for.Estoy acostumbrado a este patrón de C#, donde cada vez que se crea una función anónima, se toma una "instantánea" de los valores utilizados, por lo que el "nodo" sería diferente en cada función de controlador.

¿Cómo "tomo una instantánea" del valor actual del nodo para usar en el controlador?¿O debería usar un patrón diferente en Flex?

¿Fue útil?

Solución

El cierre sólo capta una referencia a la variable, no a su valor actual.Dado que las variables locales tienen un ámbito de función (no un ámbito de bloque), cada iteración a través del bucle crea un cierre que captura una referencia a la misma variable.

Podría extraer el código de creación de TextInput en una función separada, lo que le daría una instancia de variable separada para capturar para el cierre.Algo como esto:

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

Otros consejos

Desafortunadamente, los cierres de funciones funcionan de manera extraña o deficiente en Actionscript.Las variables sólo obtienen una "instantánea" cuando salen del alcance.Desafortunadamente, las variables tienen un ámbito de función y no un ámbito de bloque.Para que no termine funcionando como quieres.

Podrías crear un diccionario para mapear desde Entrada de texto -> nodo, o podrías esconder el nodo en el TextInput's propiedad de datos.

Desearía que lo que describiste funcionara correctamente, ya que es una forma fácil y poderosa de expresar eso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top