【问题标题】:Add feature to spark combobox to allow better binding向火花组合框添加功能以实现更好的绑定
【发布时间】:2012-09-12 08:48:19
【问题描述】:

我尝试做的事情......

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

问题...

启动后,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();
    }
}

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

【问题讨论】:

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


    【解决方案1】:

    最终的解决方案非常简单。只需将 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;
                    }
                }
            }
        }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      有几个错误,包括影响绑定的问题(如上述主题中所述)和custom text entry。作为一种解决方法,有一个 ActionScript、Flex、仅限 spark 的组合框可以修复其中的许多问题,它可以通过 open source 获得。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-26
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多