You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by "Justin Mclean (JIRA)" <ji...@apache.org> on 2013/04/17 05:41:16 UTC

[jira] [Updated] (FLEX-23486) mx:List / selectedItemsCompareFunction property is not applied correctly

     [ https://issues.apache.org/jira/browse/FLEX-23486?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Justin Mclean updated FLEX-23486:
---------------------------------

    Labels: easyfix easytest  (was: )
    
> mx:List / selectedItemsCompareFunction property is not applied correctly
> ------------------------------------------------------------------------
>
>                 Key: FLEX-23486
>                 URL: https://issues.apache.org/jira/browse/FLEX-23486
>             Project: Apache Flex
>          Issue Type: Bug
>          Components: mx: List
>    Affects Versions: Adobe Flex SDK 3.6 (Release)
>         Environment: Affected OS(s): All OS Platforms
> Browser: Firefox 3.x
> Language Found: English
>            Reporter: Adobe JIRA
>              Labels: easyfix, easytest
>
> Note: issue affects several version of Flex SDK, first noticed in 3.4, but same problem exists in latest stable build of 4.0 as well.
> Steps to reproduce:
> 1. Use mx:List control with dataProvider containing non-primitive items (like Date, for simplest case)
> 2. Use selectedItemsCompareFunction on mx:List to compare items during selection
> 3. Set selectedItems as an array of objects with references different to ones used in dataProvider
>  
>  Actual Results:
>  Runtime exception thrown:
> TypeError: Error #1010: A term is undefined and has no properties.
> 	at mx.controls.listClasses::ListBase/setSelectionDataLoop()[C:\autobuild\3.4.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:6473]
> 	at mx.controls.listClasses::ListBase/commitSelectedItems()[C:\autobuild\3.4.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:6364]
> 	at mx.controls.listClasses::ListBase/set selectedItems()[C:\autobuild\3.4.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:2942]
> 	at ListsCompare/updateLeft()[C:\Documents and Settings\sav\Adobe Flash Builder Beta 2\FileDownload\src\ListsCompare.mxml:22]
> 	at ListsCompare/__lstRight_change()[C:\Documents and Settings\sav\Adobe Flash Builder Beta 2\FileDownload\src\ListsCompare.mxml:37]
> .... 
>  Expected Results:
>  selection is applied correctly
>  Reason and possible resolution:
> Actually bug fix is super easy. The problem itself lies in fact that List temporary stores UID-to-index map of selected items in one function
>   function commitSelectedItems(items:Array):void {...}
> and afterward applies it incorrectly in another
>   function setSelectionDataLoop(items:Array, index:int, useFind:Boolean = true):void {...}
>  
> Namely, the following lines causes the problem (from setSelectionDataLoop):
> if (compareFunction(data, item))
> {
>   uid = itemToUID(data); // ISSUE IS HERE -- must be itemToUID(item)
>                         
>   selectionDataArray[proposedSelectedItemIndexes[uid]] = new ListBaseSelectionData(data, index, false);
> ...
> }
> I.e. proposedSelectedItemIndexes is indexed by UID of objects from selectedItems but here it is accessed by UID of objects from dataProvider.
>   
>  Workaround (if any):
> Given the fact that comparator is invoked right before call to itemToUID and comparator is never used in any other place, mx:List may be replaced with custom class with the following trick applied:
> package {
>   import mx.controls.List;
>   public class MyList extends List {
>     override public function set selectedItemsCompareFunction(value:Function):void {
>       super.selectedItemsCompareFunction = value == null ? null : function(a:*, b:*):Boolean {
>         isComparatorCalled = true;
>         latestComparatorParam = b;
>          return value(a, b);
>       };
>     } 
> 		
>     private var isComparatorCalled:Boolean = false;
>     private var latestComparatorParam:* = null;
> 	
>     override protected function itemToUID(data:Object):String {
>       if (!isComparatorCalled)
>         return super.itemToUID(data);
>       else {
>         var param:* = latestComparatorParam;
>         isComparatorCalled = false;
>         latestComparatorParam = null;
>         return super.itemToUID(param);
>       }
>     }
>   }
> }

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira