Проблема привязки выпадающего списка Flex (или ошибка?)
Я использую модель MVC в моем проекте Flex.
Я хотел бы связать свойства класса объекта-значения с представлением mxml, а затем изменить это представление путем изменения объекта-значения.
Что просходит:
- Установите выбранное значение на "c" - индекс 2
- Добавьте "x,y,z" перед "c"
- Нажмите ввод -> теперь индекс 5
- Нажмите ввод -> теперь индекс -1
- Смотрите 4.
Почему работает только первое обновление? Я знаю, что, наверное, упускаю что-то очевидное...
Редактировать: пример выполнения
(PS первый пост, и я не уверен, как включить подсветку MXML)
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="created(event)"
width="160" height="220">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
//===================================
// Pretend Value Object Class
[Bindable] private var list:ArrayList = null;
[Bindable] private var index:int = 0;
//===================================
protected function created(event:FlexEvent):void {
ddValues.addEventListener(FlexEvent.ENTER, update);
update();
}
private function update(... args):void {
//note selected item
trace("dropdown index: " + dd.selectedIndex);
var s:String = dd.selectedItem as String;
trace("selected item: " + s);
//build new list from csv
list = new ArrayList(ddValues.text.split(","));
trace("new list: " + ddValues.text);
trace("selected item: " + s);
//if exists in new list, set value object index
var newIndex:int = 0;
if(list)
list.toArray().forEach(function(ss:String, i:int, a:Array):void {
if(s == ss) newIndex = i;;
});
index = newIndex;
trace("new index: " + index + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
protected function ddChange(event:IndexChangeEvent):void
{
trace("selected item: " + (dd.selectedItem as String) + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
]]>
</fx:Script>
<s:Panel width="100%" height="100%" title="Drop Down Bug">
<s:layout>
<s:VerticalLayout gap="10" paddingLeft="10" paddingTop="10" paddingRight="10" paddingBottom="10"/>
</s:layout>
<s:DropDownList id="dd" dataProvider="{list}" selectedIndex="@{index}" change="ddChange(event)"></s:DropDownList>
<s:Label text="Label: {dd.selectedItem as String}" paddingTop="5" paddingBottom="5"/>
<s:Label text="Code Index: {index}" paddingTop="5" paddingBottom="5"/>
<s:Label text="DropDown Index: {dd.selectedIndex}" paddingTop="5" paddingBottom="5"/>
<s:TextInput id="ddValues" text="a,b,c,d,e"/>
</s:Panel>
</s:Application>
И вот выходной отредактированный код и добавленные следы. Вот вывод, который показывает мою проблему:
dropdown index: -1
selected item: null
new list: a,b,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
selected item: c (dropdown index: 2)
===
dropdown index: 2
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: 5
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: -1
selected item: null
new list: a,b,x,y,z,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
1 ответ
О, я вижу, что происходит сейчас. При замене всего списка выбранный элемент будет нулевым, поскольку выбранный элемент был в старом списке. Вам нужно сохранить выбранный элемент при его выборе, а затем выполнить сравнение с этим сохраненным элементом, а не с текущим выбранным (нулевым) элементом.
Обратите внимание, что то, что вы делаете, никоим образом не является MVC, если только вы не переопределили MVC в значении "Модель, Представление и Контроллер - это одно и то же". В MVC модель не имеет представления о представлении, а представление имеет доступ только для чтения той части модели, которая необходима для отображения данных. У него нет доступа на запись к модели. Это функция контроллера.