сохранение списка selectedIndex между перезагрузками привязки данных в Flex - PullRequest
1 голос
/ 01 января 2009

В моем интерфейсе Flex у меня есть несколько компонентов List, которые связаны с данными ArrayCollections. Я обнаружил, что при обновлении ArrayCollections (веб-службами) и обновлении привязок данных для списков каждый список сбрасывается, а его selectedIndex удаляется. Это проблема, если пользователь находится в середине задачи и уже выбрал элемент в списке, но еще не отправил форму.

Я знаю, как можно объединить некоторые ActionScript для решения этих случаев, но знаете ли вы какой-нибудь способ сделать это более естественным образом, используя привязку данных Flex или утилиты событий общего назначения?

Как всегда, спасибо!

Ответы [ 2 ]

1 голос
/ 03 января 2009

У нас есть класс 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;
        }
    }               
}
}
1 голос
/ 01 января 2009

Мне нравится использовать найденный класс наблюдения здесь для вызова функции при изменении данных. Он принимает два параметра: данные для просмотра и функцию для вызова. (Экономит ваше время повторения сеттеров и геттеров все время)

Я бы сохранял selectedItem, когда он выбран и когда данные обновляются, повторно выберите этот элемент, просматривая список и снова выбирая элемент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...