У нас есть класс SelectionRestorer, который делает именно это. Просто добавьте его в MXML и установите его цель в список / выпадающий список / все, что вы хотите заполнить, и он сделает все за вас.
НТН,
Sam
Мы нанимаем! Разработчики и QA в Вашингтоне (округ Колумбия) (или желающие переехать) должны отправить резюме по адресу careers@blinemedical.com.
package com.atellis.common.controls {
import flash.events.Event;
import flash.events.EventDispatcher;
import mx.events.CollectionEvent;
import mx.events.ListEvent;
public class SelectionRestorer extends EventDispatcher
{
private var previousSelectedItems:Array;
private var _compareField:String;
[Bindable("compareFieldChanged")]
public function get compareField():String {
return _compareField;
}
public function set compareField(value:String):void {
_compareField = value;
dispatchEvent(new Event("compareFieldChanged"));
}
private var _compareFunction:Function;
[Bindable("compareFunctionChanged")]
public function get compareFunction():Function {
return _compareFunction;
}
public function set compareFunction(value:Function):void {
_compareFunction = value;
dispatchEvent(new Event("compareFunctionChanged"));
}
private var _target:Object;
[Bindable("targetChanged")]
public function get target():Object {
return _target;
}
public function set target(value:Object):void {
if (_target) {
if (_target.dataProvider) {
_target.dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE, dataChangeHandler);
}
_target.removeEventListener(ListEvent.CHANGE, selectionChangeHandler);
_target.removeEventListener(CollectionEvent.COLLECTION_CHANGE, dataChangeHandler);
}
_target = value;
if (value) {
value.addEventListener(ListEvent.CHANGE, selectionChangeHandler, false, 0, true);
value.addEventListener(CollectionEvent.COLLECTION_CHANGE, dataChangeHandler, false, 100.0, true);
if (value.dataProvider) {
value.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, dataChangeHandler, false, 100.0, true);
}
}
dispatchEvent(new Event("targetChanged"));
}
public function refresh():void {
if (useMultipleSelect) {
previousSelectedItems = target.selectedItems;
} else {
previousSelectedItems = [target.selectedItem];
}
}
public function clear():void {
previousSelectedItems = null;
}
private function compareFieldFunction(o1:Object, o2:Object):Boolean {
if (o1 == null || o2 == null) {
return false;
}
var v1:Object = o1[compareField];
var v2:Object = o2[compareField];
return v1 != null && v2 != null && v1 == v2;
}
private function compareEqualityFunction(o1:Object, o2:Object):Boolean {
if (o1 == null || o2 == null) {
return false;
}
return o1 == o2;
}
private function get useMultipleSelect():Boolean {
return "selectedItems" in target && "allowMultipleSelection" in target && target.allowMultipleSelection;
}
private function selectionChangeHandler(event:ListEvent):void {
refresh();
}
private function dataChangeHandler(event:CollectionEvent):void {
if (previousSelectedItems == null || previousSelectedItems.length == 0) {
return;
}
if (target.dataProvider == null) {
previousSelectedItems = null;
return;
}
var comparer:Function = compareFunction;
if (comparer == null) {
if (compareField == null) {
comparer = compareEqualityFunction;
} else {
comparer = compareFieldFunction;
}
}
// when you assign an array to ListBase.selectedItems, it removes all items from the array,
// so we need to build two arrays, one to assign, and one for current state
var indices:Array = new Array();
var items:Array = new Array();
var dpIndex:int = 0;
for each(var newItem:Object in target.dataProvider) {
for(var i:int = 0; i<previousSelectedItems.length; i++) {
if (comparer(newItem, previousSelectedItems[i])) {
indices.push(dpIndex);
items.push(newItem);
previousSelectedItems.splice(i, 1);
break;
}
}
if (previousSelectedItems.length == 0) {
break;
}
dpIndex++;
}
target.validateNow();
if (useMultipleSelect) {
target.selectedIndices = indices;
} else {
target.selectedIndex = indices[0];
}
if (items.length) {
previousSelectedItems = items;
} else {
previousSelectedItems = null;
}
}
}
}