Apache flex 保留在Flex中数据绑定重新加载之间选择的索引列表

Apache flex 保留在Flex中数据绑定重新加载之间选择的索引列表,apache-flex,actionscript-3,data-binding,Apache Flex,Actionscript 3,Data Binding,在我的Flex界面中,我有几个列表组件是绑定到ArrayCollections的数据。我发现当ArrayCollections被更新(通过Web服务)并且列表的数据绑定被更新时,每个列表都被重置,其selectedIndex被删除。如果用户处于任务中间并且已经在列表中选择了项,但尚未提交表单,则这是一个问题。 我知道我如何拼凑一些ActionScript来处理这些情况,但是您知道有什么方法可以使用Flex的数据绑定或通用事件实用程序更自然地处理这些情况吗 一如既往,谢谢 我喜欢使用发现的obse

在我的Flex界面中,我有几个列表组件是绑定到ArrayCollections的数据。我发现当ArrayCollections被更新(通过Web服务)并且列表的数据绑定被更新时,每个列表都被重置,其selectedIndex被删除。如果用户处于任务中间并且已经在列表中选择了项,但尚未提交表单,则这是一个问题。

我知道我如何拼凑一些ActionScript来处理这些情况,但是您知道有什么方法可以使用Flex的数据绑定或通用事件实用程序更自然地处理这些情况吗


一如既往,谢谢

我喜欢使用发现的observe类在数据更改时调用函数。它需要两个参数:监视数据和调用函数。(节省您一直重复setter和getter的时间)


当选择selectedItem并更新数据时,我会存储它。通过循环列表并再次选择该项,重新选择该项。

我们有一个SelectionRestorer类,可以完成此操作。只需将其添加到MXML中,并将其目标设置为list/combobox/您想要重新填充的任何内容,它就会为您完成所有监视工作

嗯,

萨姆


我们在招聘!华盛顿特区的开发人员和QA(或寻求搬迁)应将简历发送至careers@blinemedical.com.


package com.atellis.common.controls{
导入flash.events.Event;
导入flash.events.EventDispatcher;
导入mx.events.CollectionEvent;
导入mx.events.ListEvent;
公共类SelectionRestore扩展了EventDispatcher
{
private var previousSelectedItems:数组;
private var\u compareField:String;
[可绑定(“compareFieldChanged”)]
公共函数get compareField():字符串{
返回比较字段;
}
公共函数集compareField(值:字符串):void{
_比较字段=值;
dispatchEvent(新事件(“compareFieldChanged”);
}
私有变量比较函数:函数;
[可绑定(“compareFunctionChanged”)]
公共函数get compareFunction():函数{
返回比较函数;
}
公共函数集比较函数(值:函数):void{
_比较函数=值;
dispatchEvent(新事件(“compareFunctionChanged”);
}
私有var_目标:对象;
[可绑定(“目标更改”)]
公共函数get target():对象{
返回目标;
}
公共功能集目标(值:对象):无效{
如果(_目标){
if(_target.dataProvider){
_target.dataProvider.removeEventListener(CollectionEvent.COLLECTION\u CHANGE,dataChangeHandler);
}
_target.removeEventListener(ListEvent.CHANGE,selectionChangeHandler);
_target.removeEventListener(CollectionEvent.COLLECTION\u CHANGE,dataChangeHandler);
}
_目标=价值;
如果(值){
value.addEventListener(ListEvent.CHANGE,selectionChangeHandler,false,0,true);
value.addEventListener(CollectionEvent.COLLECTION\u CHANGE,dataChangeHandler,false,100.0,true);
if(value.dataProvider){
value.dataProvider.addEventListener(CollectionEvent.COLLECTION\u CHANGE,dataChangeHandler,false,100.0,true);
}
}
调度事件(新事件(“目标更改”);
}
公共函数refresh():void{
如果(使用多重选择){
previousSelectedItems=target.selectedItems;
}否则{
previousSelectedItems=[target.selectedItem];
}
}
公共函数clear():void{
previousSelectedItems=null;
}
私有函数compareFieldFunction(o1:Object,o2:Object):布尔值{
如果(o1==null | | o2==null){
返回false;
}
var v1:Object=o1[compareField];
var v2:Object=o2[compareField];
返回v1!=null&&v2!=null&&v1==v2;
}
私有函数CompareQualityFunction(o1:Object,o2:Object):布尔值{
如果(o1==null | | o2==null){
返回false;
}
返回o1==o2;
}
私有函数get-useMultipleSelect():布尔值{
在target&&target.allowMultipleSelection中的target&&allowMultipleSelection中返回“selectedItems”;
}
私有函数selectionChangeHandler(事件:ListEvent):void{
刷新();
}
私有函数dataChangeHandler(事件:CollectionEvent):void{
如果(previousSelectedItems==null | | previousSelectedItems.length==0){
返回;
}
if(target.dataProvider==null){
previousSelectedItems=null;
返回;
}
变量比较器:函数=比较函数;
if(比较器==null){
if(compareField==null){
比较器=比较器质量函数;
}否则{
comparer=compareFieldFunction;
}
}
//将数组分配给ListBase.selectedItems时,它会从数组中删除所有项,
//所以我们需要构建两个数组,一个用于分配,一个用于当前状态
变量索引:数组=新数组();
变量项:数组=新数组();
var-dpIndex:int=0;
对于每个(var newItem:target.dataProvider中的对象){
对于(变量i:int=0;i
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;
        }
    }               
}
}