Uploaded image for project: 'Apache Flex'
  1. Apache Flex
  2. FLEX-23486

mx:List / selectedItemsCompareFunction property is not applied correctly

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • Adobe Flex SDK 3.6 (Release)
    • Apache Flex 4.10.0
    • mx: List
    • Affected OS(s): All OS Platforms
      Browser: Firefox 3.x
      Language Found: English

    Description

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

      }
      }
      }

      Attachments

        Activity

          People

            Unassigned Unassigned
            adobejira Adobe JIRA
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: