Pergunta

No Flex, tenho um documento xml como o seguinte:

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

Em tempo de execução, desejo criar um controle TextInput para cada nó na raiz e vincular os valores aos valores no XML.Pelo que sei, não posso usar BindingUtils para vincular a nós e4x em tempo de execução (diga-me se estou errado aqui!), então estou tentando fazer isso manualmente:

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

Meu problema é que quando o usuário edita um dos TextInputs, o nó atribuído é sempre o último encontrado no loop for.Estou acostumado com esse padrão do C#, onde cada vez que uma função anônima é criada, um "instantâneo" dos valores dos valores usados ​​é obtido, então o "nó" seria diferente em cada função manipuladora.

Como faço para "tirar um instantâneo" do valor atual do nó para usar no manipulador?Ou devo usar um padrão diferente no Flex?

Foi útil?

Solução

O fechamento captura apenas uma referência à variável, não ao seu valor atual.Como as variáveis ​​locais têm escopo de função (não de bloco), cada iteração através do loop cria um fechamento que captura uma referência à mesma variável.

Você poderia extrair o código de criação do TextInput em uma função separada, o que forneceria uma instância de variável separada para capturar para o fechamento.Algo assim:

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

Outras dicas

Infelizmente, os fechamentos de funções funcionam de maneira estranha/mal no Actionscript.As variáveis ​​só obtêm um "instantâneo" quando saem do escopo.Infelizmente, as variáveis ​​têm escopo de função e não de bloco.Então não acaba funcionando como você deseja.

Você poderia criar um dicionário para mapear TextInput -> nó, ou você pode ocultar o nó no TextInput's propriedade de dados.

Gostaria que o que você descreveu funcionasse corretamente, pois é uma maneira fácil/poderosa de expressar isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top