1

私がやろうとしていること...

より高度なdropDownListコンポーネントを実装しようとしています。基本的に任意の値を取ることができる新しいプロパティselectedValueを追加しました。現時点では、コンポーネントはselectedValueをデータプロバイダーアイテムの「id」と一致させようとするだけです。サンプルをデバッグすると、問題なく表示され、selectedIndexはselectedValueに基づいて設定されます。

問題...

selectedItemはstartUp後にdropDownListに表示されません。ドロップダウンボタンをクリックした場合にのみ表示されます。選択されているが、ビューに表示されていないことを意味します。

アプリケーションの起動後...

クリックして画像を見る

カスタムコンポーネントの矢印ボタンをクリックすると...

クリックして画像を見る

そしてここにコードがあります...

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();
    }
}

これを修正する方法はありますか?

4

2 に答える 2

0

最終的な解決策は非常に簡単です。super.commitProperties();を置くだけです。オーバーライドするcommitProperties()メソッドの最後。

それは絶対に意味があります。スーパーメソッドですでに処理されている独自のcommitProperties()でプロパティ(selectedIndex)を操作しているためです。したがって、selectedIndexの更新は、commitProperties()が次に呼び出されるまで表示されません。

したがって、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;
                }
            }
        }
    }

お役に立てれば。

于 2012-10-13T04:14:11.060 に答える
0

<s:ComboBox>には、バインディングに影響する問題(上記のトピックで説明)やカスタムテキスト入力など、いくつかのバグがあります。回避策として、これらの問題の多くを修正するActionScript、Flex、sparkのみのコンボボックスがあり、オープンソースとして利用できます。

于 2015-04-13T22:55:55.410 に答える