Editando XML no Flex usando e4x
-
09-06-2019 - |
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?
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.