Question

Dans Flex, j'ai un document XML tel que:

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

Au moment de l'exécution, je souhaite créer un contrôle TextInput pour chaque nœud situé sous la racine et associer les valeurs aux valeurs du code XML. Autant que je sache, je ne peux pas utiliser BindingUtils pour me lier à des nœuds e4x au moment de l'exécution (dites-moi si je me trompe ici!), J'essaie donc de le faire à la main:

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

Mon problème est que lorsque l'utilisateur édite l'un des TextInputs, le nœud affecté est toujours le dernier nœud rencontré dans la boucle for. Je suis habitué à ce modèle depuis C #, où chaque fois qu’une fonction anonyme est créée, un "instantané". des valeurs des valeurs utilisées est prise, donc "noeud" serait différent dans chaque fonction de gestionnaire.

Comment puis-je "prendre un instantané"? de la valeur actuelle du noeud à utiliser dans le gestionnaire? Ou devrais-je utiliser un modèle différent dans Flex?

Était-ce utile?

La solution

La fermeture ne capture qu'une référence à la variable, pas sa valeur actuelle. Etant donné que les variables locales ont une portée fonctionnelle (et non une portée générale), chaque itération de la boucle crée une fermeture qui capture une référence à la même variable.

Vous pouvez extraire le code de création TextInput dans une fonction distincte, ce qui vous donnerait une instance de variable distincte à capturer pour la fermeture. Quelque chose comme ça:

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

Autres conseils

Malheureusement, les fermetures de fonctions fonctionnent bizarrement / mal dans ActionScript. Les variables ne reçoivent qu'un & snapshot " quand ils vont hors de portée. Malheureusement, les variables sont liées à la fonction et non au bloc. Cela ne fonctionne donc pas comme vous le souhaitez.

Vous pouvez créer un dictionnaire à mapper à partir de TextInput - > noeud , ou vous pouvez cacher le noeud dans la propriété de données de TextInput .

Je souhaite que ce que vous venez de décrire fonctionne correctement car c'est un moyen simple et puissant de l'exprimer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top