Редактирование XML во Flex с использованием e4x - PullRequest
1 голос
/ 15 сентября 2008

В 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?

Ответы [ 2 ]

2 голосов
/ 15 сентября 2008

Закрытие захватывает только ссылку на переменную, а не ее текущее значение. Поскольку локальные переменные находятся в функциональной области (а не в блоке), каждая итерация цикла создает замыкание, которое фиксирует ссылку на ту же переменную

Вы можете извлечь код создания 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;
}
2 голосов
/ 15 сентября 2008

К сожалению, замыкания функций работают странно / плохо в Actionscript. Переменные получают «снимок» только тогда, когда они выходят из области видимости. К сожалению, переменные являются областью действия функции, а не областью блока. Так что это не сработает так, как вы хотите.

Вы можете создать словарь для сопоставления из TextInput -> node , или вы можете сохранить узел в свойстве данных TextInput's.

Я бы хотел, чтобы то, что вы описали, работало правильно, поскольку это простой / мощный способ выразить это.

...