简体   繁体   中英

Flex Drop Down List Binding Issue (or Bug?)

I'm using the MVC model in my flex project.

What I'd like is to bind a value object's class properties to a view mxml, then change that view by altering the value object.

What happens:

  1. Set the selected value to 'c' - index 2
  2. Add 'x,y,z,' before 'c'
  3. Hit enter -> now index 5
  4. Hit enter -> now index is -1
  5. See 4.

Why does only the first update work ? I know I'm probably missing something obvious...

Edit: Running Example

(PS first post and im not sure how to turn on MXML highlighting)

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

And heres the output Edited code and added traces. Heres the output that shows my problem:

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)
===

Oh, I see what's going on now. When you replace the whole list, the selected item will be null, because the item that was selected was in the old list. You'll need to store the selected item when it is selected, and then do the comparison against that stored item, not the current selected (null) item.

Note that what you're doing is in no way MVC, unless you've redefined MVC to mean "Model, View, and Controller are all the same thing." In MVC, the model has no idea of the view, and the view only has access to read as much of the model as it needs to to display the data. It does not have write access to the model. That is the function of the controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM