添加功能以激发组合框,以实现更好的绑定

时间:2012-09-20 01:21:59

标签: data-binding drop-down-menu actionscript flex-spark

我尝试做什么...

我正在尝试实现更高级的dropDownList组件。我添加了一个新属性selectedValue,它基本上可以取任何值。目前,组件仅尝试将selectedValue与dataprovider项的“id”匹配。当我调试样本它看起来很好时,selectedIndex基于selectedValue设置。

问题...

在startUp之后,selectedItem不会出现在dropDownList中,只有在我单击下拉按钮时才会出现。表示已选中但未在视图中显示。

申请启动后......

click to see image

点击自定义组件上的箭头按钮...

click to see image

以下是代码......

MAIN.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
     xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="ch.fa.ed.ui.components.*"
     width="100%" height="100%" >

<fx:Script>
    <![CDATA[

        import mx.collections.ArrayCollection;

        private var _dpList : ArrayCollection;

        public function get dpList() : ArrayCollection {
            if (_dpList == null) {
                _dpList = new ArrayCollection();

                // create items
                var person1 : Object = new Object();
                person1.id = 10;
                person1.name = "Bush";

                var person2 : Object = new Object();
                person2.id = 12;
                person2.name = "Obama";

                var person3 : Object = new Object();
                person3.id = 30;
                person3.name = "Clinton";

                _dpList.addItem(person1);
                _dpList.addItem(person2);
                _dpList.addItem(person3);
            }

            return _dpList;
        }

        public function set dpList(dpList : ArrayCollection) : void {
            _dpList = dpList;
        }
    ]]>
</fx:Script>
<s:VGroup>
    <s:DropDownList id="ddList" dataProvider="{dpList}" labelField="name" selectedIndex="2"/>
    <components:EdDropDownList id="ddList2" dataProvider="{dpList}" labelField="name" selectedValue="30"/>
</s:VGroup>
</s:Group>

EdDrowDownList.as

package ch.fa.ed.ui.components {

import mx.collections.IList;

import spark.components.DropDownList;

/**
 * @author Michael Wittwer <michael.wittwer@falution.ch>
 * @date 20.09.2012
 */
public class EdDropDownList extends DropDownList {

    /* ******************************************************************************************************
     * fields                                                                                               *
     ****************************************************************************************************** */
    private var _selectedValue : *;

    /* ******************************************************************************************************
     * member variables                                                                                     *
     ****************************************************************************************************** */
    private var selectedValueChanged : Boolean;

    private var dataProviderChanged : Boolean;

    public function EdDropDownList() {
        super();
    }

    /*
     * overriding the commitProperties method to make sure the selectedValue field gets represented in ui
     */
    override protected function commitProperties() : void {
        super.commitProperties();

        if (selectedValueChanged && dataProviderChanged) {
            // find the item mathing selectedValue and set index
            if (selectedValue != null && dataProvider != null) {
                for (var i : int = 0; i < dataProvider.length; i++) {
                    var item : * = dataProvider.getItemAt(i);
                    if (item.id == selectedValue) {
                        selectedIndex = i;
                        break;
                    }
                }
            }

            dataProviderChanged = false;
            selectedValueChanged = false;
        }

        if (selectedValueChanged) {
            selectedValueChanged = false;

            // find the item mathing selectedValue and set index
            if (selectedValue != null && dataProvider != null) {
                for (var i : int = 0; i < dataProvider.length; i++) {
                    var item : * = dataProvider.getItemAt(i);
                    if (item.id == selectedValue) {
                        selectedIndex = i;
                        break;
                    }
                }
            }
        }

        if (dataProviderChanged) {
            dataProviderChanged = false;
            // find the item mathing selectedValue and set index
            if (selectedValue != null && dataProvider != null) {
                for (var i : int = 0; i < dataProvider.length; i++) {
                    var item : * = dataProvider.getItemAt(i);
                    if (item.id == selectedValue) {
                        selectedIndex = i;
                        break;
                    }
                }
            }
        }
    }

    /* ******************************************************************************************************
     * getter and setter methods                                                                            *
     ****************************************************************************************************** */
    [Bindable]
    public function get selectedValue() : * {
        return _selectedValue;
    }

    public function set selectedValue(selectedValue : *) : void {
        _selectedValue = selectedValue;
        selectedValueChanged = true;

        invalidateProperties();
    }

    [Bindable]
    override public function set dataProvider(value : IList) : void {
        super.dataProvider = value;
        dataProviderChanged = true;
        invalidateProperties();
    }
}

任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

最终解决方案非常简单。只需把super.commitProperties();在重写的commitProperties()方法的末尾。

这绝对是一种感觉。因为我们在自己的commitProperties()中操作属性(selectedIndex),这已经在super方法中处理了。因此,在下次调用commitProperties()之前,selectedIndex上的更新将不可见。

所以对于工作组件,commitProperties()看起来像这样:

override protected function commitProperties() : void {
        if (selectedValueChanged && dataProviderChanged) {
            // find the item mathing selectedValue and set index
            updateSelectedIndex();

            dataProviderChanged = false;
            selectedValueChanged = false;
        }

        if (selectedValueChanged) {
            selectedValueChanged = false;

            // find the item mathing selectedValue and set index
            updateSelectedIndex();
        }

        if (dataProviderChanged) {
            dataProviderChanged = false;
            // find the item mathing selectedValue and set index
            updateSelectedIndex();
        }

        super.commitProperties();
    }

    private function updateSelectedIndex() : void {
        if (selectedValue != null && dataProvider != null) {
            for (var i : int = 0; i < dataProvider.length; i++) {
                var item : * = dataProvider.getItemAt(i);
                if (item.id == selectedValue) {
                    selectedIndex = i;
                    break;
                }
            }
        }
    }

希望这有帮助。

答案 1 :(得分:0)

&lt; s:ComboBox&gt;有几个错误,包括影响绑定的问题(如上文主题所述)和custom text entry。作为一种解决方法,有一个ActionScript,Flex,仅限spark的组合框可以修复许多这些问题,它可以open source获得。