【问题标题】:spark Combobox selection is not visible if list changes如果列表更改,火花组合框选择不可见
【发布时间】:2015-04-06 12:32:31
【问题描述】:

我正在使用 Spark Combobox 和过滤器函数来过滤 firstNamelastName 中的字符。当用户键入“a”时,下拉列表将显示所有已过滤的项目,并在下拉列表中选择“aram,babu”,并在文本输入中将文本显示为“aram,babu”。如果用户按下“r”,文本输入显示“aram,babu”,但下拉列表选择消失。在下拉菜单外按 Enter 或单击鼠标会导致选择了错误的项目(最后一项,即“armu,babu”)。

<?xml version="1.0"?>
<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" xmlns:local="*">
<fx:Script><![CDATA[
    import mx.collections.ArrayCollection;


    private function labelField(item:Object):String {
        if (item && item as SalesPerson && item.lastName && item.firstName) {
            return item.firstName + "," + item.lastName;
        }
        return "";
    }

    private var arr:ArrayCollection;
    private var arr1:ArrayCollection;
    private var salesPer:SalesPerson;
    private function getData():ArrayCollection
    {
        arr1 = new ArrayCollection();
        var salesPerson:SalesPerson = new SalesPerson();
        salesPerson.userName = "ravi kumar";
        salesPerson.firstName = "ravi";
        salesPerson.lastName = "kumar";

        var salesPerson1:SalesPerson = new SalesPerson();
        salesPerson1.userName = "kiran kumar";
        salesPerson1.firstName = "kiran";
        salesPerson1.lastName = "kumar";

        var salesPerson2:SalesPerson = new SalesPerson();
        salesPerson2.userName = "james bond";
        salesPerson2.firstName = "james";
        salesPerson2.lastName = "bond";

        var salesPerson3:SalesPerson = new SalesPerson();
        salesPerson3.userName = "ravi babu";
        salesPerson3.firstName = "ravi";
        salesPerson3.lastName = "babu";

        var salesPerson4:SalesPerson = new SalesPerson();
        salesPerson4.userName = "rakesh babu";
        salesPerson4.firstName = "rakesh";
        salesPerson4.lastName = "babu";

        var salesPerson5:SalesPerson = new SalesPerson();
        salesPerson5.userName = "ramesh babu";
        salesPerson5.firstName = "ramesh";
        salesPerson5.lastName = "babu";

        var salesPerson6:SalesPerson = new SalesPerson();
        salesPerson6.userName = "aram babu";
        salesPerson6.firstName = "aram";
        salesPerson6.lastName = "babu";

        var salesPerson7:SalesPerson = new SalesPerson();
        salesPerson7.userName = "armu babu";
        salesPerson7.firstName = "armu";
        salesPerson7.lastName = "babu";
        arr1.addItem(salesPerson);
        arr1.addItem(salesPerson1);
        arr1.addItem(salesPerson2);
        arr1.addItem(salesPerson3);
        arr1.addItem(salesPerson4);
        arr1.addItem(salesPerson5);
        arr1.addItem(salesPerson6);
        arr1.addItem(salesPerson7);

       return arr1;
    }

    ]]></fx:Script>

<s:VGroup width="100%" height="100%">
     <local:FilterCombo labelFunction="labelField" dataProvider="{getData()}"/>
</s:VGroup>

</s:Application>


<?xml version="1.0"?>
    <s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:s="library://ns.adobe.com/flex/spark"
                xmlns:mx="library://ns.adobe.com/flex/mx" click="clickHandler(event)">
        <fx:Script>
            <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.collections.IList;

            import spark.events.TextOperationEvent;

            private var unfilteredDataProvider:IList;

            override public function set dataProvider(value:IList):void {
                super.dataProvider = value;

                unfilteredDataProvider = value;
            }

            override protected function textInput_changeHandler(event:TextOperationEvent):void {
                super.textInput_changeHandler(event);

                if (unfilteredDataProvider is ArrayCollection) {
                    ArrayCollection(unfilteredDataProvider).filterFunction = filterMatches;
                    ArrayCollection(unfilteredDataProvider).refresh();

                    super.dataProvider = new ArrayCollection(unfilteredDataProvider.toArray());
                }


            }

            protected function filterMatches(item:Object):Boolean {
               if (item && item.lastName && item.firstName) {
                    if (String(item.lastName + item.firstName).toLowerCase().indexOf(textInput.text.slice(0, textInput.selectionAnchorPosition).toLowerCase()) > -1) {
                        //     trace("traderDoFilter true")
                        return true;
                    }
                }
                return false;
            }

            private function clickHandler(event:MouseEvent):void {

            }
            ]]>
    </fx:Script>
    </s:ComboBox>

【问题讨论】:

    标签: actionscript-3 apache-flex flex4 flex3 flex4.5


    【解决方案1】:

    Combobox 搜索基本上是基于labelfield 工作的,你可以看到Combobox 框架代码。

    验证下面提到的功能: 组合框 -> 进程输入字段(函数)

    if (itemMatchingFunction != null)//itemMatchingFunction allways null untill we assign our callback function
             matchingItems = itemMatchingFunction(this, textInput.text);
        else
             matchingItems = findMatchingItems(textInput.text);//calling by default

    所以我们需要将自定义回调函数分配给itemMatchingFunction(public)

    我对你的代码做了一些修改试试这个,它有一些错误

    <?xml version="1.0" encoding="utf-8"?>
    <s:ComboBox xmlns:fx="http://ns.adobe.com/mxml/2009"
    			xmlns:s="library://ns.adobe.com/flex/spark"
    			xmlns:mx="library://ns.adobe.com/flex/mx" click="clickHandler(event)">
    	<fx:Script>
    		<![CDATA[
    			import mx.collections.ArrayCollection;
    			import mx.collections.IList;
    			
    			import spark.events.TextOperationEvent;
    			import spark.utils.LabelUtil;
    			
    			private var unfilteredDataProvider:IList;
    			namespace mx_internal;
    			override public function set dataProvider(value:IList):void {
    				super.dataProvider = value;
    				this.itemMatchingFunction = itemMatchingFunction1;
    			}
    			
    			 override protected function textInput_changeHandler(event:TextOperationEvent):void {
    				super.textInput_changeHandler(event);
    				
    				if (dataProvider is ArrayCollection) {
    					ArrayCollection(dataProvider).filterFunction = filterMatches;
    					ArrayCollection(dataProvider).refresh();
    				}
    				
    				
    			}
    			
    			protected function filterMatches(item:Object):Boolean {
    				if (item && item.lastName && item.firstName) {
    					if (String(item.lastName +","+ item.firstName).toLowerCase().indexOf(textInput.text.slice(0, textInput.selectionAnchorPosition).toLowerCase()) > -1) {
    						return true;
    					}
    				}
    				return false;
    			} 
    			
    			
    			/**
    			 *  @private 
    			 */ 
    			// Returns an array of possible values
    			private function itemMatchingFunction1(comB:ComboBox,input:String):Vector.<int>
    			{
    				// For now, just select the first match
    				var startIndex:int;
    				var stopIndex:int;
    				var retVal:int;  
    				var retVector:Vector.<int> = new Vector.<int>;
    				retVal = findStringLoop(input, 0, dataProvider.length); 
    				if (retVal != -1)
    					retVector.push(retVal);
    				return retVector;
    			}
    			
    			
    			/**
    			 *  @private
    			 */
    			 function findStringLoop(str:String, startIndex:int, stopIndex:int):Number
    			{
    				// Try to find the item based on the start and stop indices. 
    				for (startIndex; startIndex != stopIndex; startIndex++)
    				{
    					var itmStr:String = itemToLabel(dataProvider.getItemAt(startIndex));
    					
    					itmStr = itmStr.substring(0, str.length);
    					if (str == itmStr || str.toUpperCase() == itmStr.toUpperCase())
    					{
    						return startIndex;
    					}
    				}
    				return -1;
    			}
    			
    			/**
    			 *  Given a data item, return the correct text a renderer
    			 *  should display while taking the <code>labelField</code> 
    			 *  and <code>labelFunction</code> properties into account. 
    			 *
    			 *  @param item A data item 
    			 *  
    			 *  @return String representing the text to display for the 
    			 *  data item in the  renderer. 
    			 *  
    			 *  @langversion 3.0
    			 *  @playerversion Flash 10
    			 *  @playerversion AIR 1.5
    			 *  @productversion Flex 4
    			 */
    			override public function itemToLabel(item:Object):String
    			{
    				if (item && item.lastName && item.firstName)
    					return item.lastName +","+ item.firstName;
    				
    				return item[labelField];
    				
    			}
    			
    			
    		]]>
    	</fx:Script>
    </s:ComboBox>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-08
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 2017-10-08
      • 2015-10-04
      相关资源
      最近更新 更多