0

Я показываю задачи планирования проекта Задачи в приложении Flex, которые я разрабатываю, и я пытаюсь фильтровать элементы, отображаемые в AdvancedDataGrid (ADG), так что только задачи, которые начинаются позже пользователя выбранная дата.Flex - Фильтрация AdvancedDataGrid с иерархическими данными

Вот класс VoTask:

public class VoTask { 

    public var taskId:int; 
    public var taskProjectId:int; 
    public var taskParentId:int; 
    public var taskName:String; 
    public var taskStartDate:Date; 
    public var taskEndDate:Date; 
    public var taskType:String; 
    public var taskStatus:String; 
    public var children:/*Task*/Array; 

    // Constructor. 
    public function VoTask() { 
    } 
} 

Большинство задач являются дети родительских суммарных задач и эта иерархическая структура может быть около 5 глубоко.

В моей модели плоский массив данных задачи из базы данных SQL помещается в массив ArrayCollection как набор сильно типизированных объектов задачи, называемых tasksFlat.

Чтобы подготовить данные для отображения в качестве иерархии, у меня есть функция, которая выполняет итерацию через ArrayCollection tasksFlat и, используя taskParentId, помещает каждую Задачу в соответствующее дочернее свойство своего родителя. Это дает мне массив ArrayCollection tasksHierarchical, содержащий одну главную родительскую задачу верхнего уровня и все остальные задачи, иерархически организованные в качестве дочерних элементов.

Мои AdvancedDataGrid в настоящее время выглядит следующим образом:

<mx:AdvancedDataGrid 
     id="myADG" 
     displayItemsExpanded="false" 
     horizontalScrollPolicy="auto" 
     headerStyleName="adgHeaderStyle" 
     creationComplete="{presenter.onTasksAdvancedDataGridCreationComplete(event)}" 
     width="100%" height="100%"> 

<mx:dataProvider> 
    <mx:HierarchicalData source="{presenter.tasksHierarchical}" childrenField="children"/> 
</mx:dataProvider> 

    <mx:columns> 
     <mx:AdvancedDataGridColumn id="nameAdvancedDataGridColumn" dataField="taskName" headerText="Task" width="650"/> 
     <mx:AdvancedDataGridColumn dataField="taskStatus" headerText="Status" width="72"/> 
     <mx:AdvancedDataGridColumn id="startDateAdvancedDataGridColumn" dataField="taskStartDate" headerText="Start" width="160"/> 
     <mx:AdvancedDataGridColumn id="endDateAdvancedDataGridColumn" dataField="taskEndDate" headerText="End" width="160"/> 
     <mx:AdvancedDataGridColumn headerText="" width="64"/> 
    </mx:columns> 

    <mx:rendererProviders> 

     <mx:AdvancedDataGridRendererProvider 
       column="{startDateAdvancedDataGridColumn}" 
       renderer="itemRenderers.TaskStartDate_ItemRenderer"/> 

     <mx:AdvancedDataGridRendererProvider 
       column="{endDateAdvancedDataGridColumn}" 
       renderer="itemRenderers.TaskEndDate_ItemRenderer"/> 

    </mx:rendererProviders> 

</mx:AdvancedDataGrid> 

Пользовательский интерфейс включает в себя DateChooser. В настоящее время, когда изменения даты применяю filterFunction (в моем Presenter) следующим образом:

private function onSelectedDateChanged(event:Event):void { 

    // Set the filterFunction for the tasks data. 
    tasksHierarchical.filterFunction = tasksFilterFunction; 

    // Refresh the tasks AdvancedDataGrid data source. 
    tasksHierarchical.refresh(); 

} 

private function tasksFilterFunction(obj:Object):Boolean{ 

    //the logic to decide if an element needs to be shown or not. 
    var _task:VoTask = VoTask(obj); 
    var _returnValue:Boolean; 

    if (_task.taskEndDate < model.selectedDate) { 
     _returnValue = false; 
    } else { 
     _returnValue = true; 
    } 

    return _returnValue; 
} 

На отладки я считаю, что только верхний уровень родительского Task реагирует на функцию фильтра.

Существует около 4000 задач для изучения пользователем, и я обеспокоен тем, что если мне придется перебирать всех детей для применения функции фильтра, производительность будет неудовлетворительной. Могу ли я фильтровать только отображаемые элементы?

Возможно, я собираюсь сделать это неправильно, любые рекомендации будут очень желанными.

Благодаря

+0

Привет, У меня есть то же требование, что и вы. Не могли бы вы рассказать о том, как вы реализовали наемные ряды в ADG с фильтрами в столбце? Цените, если вы можете мне помочь. – Pro

ответ

0

Когда вы применяете фильтрацию на ArrayCollection он всегда получает применяется на первом уровне. В вашем случае вам нужно либо применить фильтрацию рекурсивно, либо вы можете переопределить HierarchicalData.getChildren(node:Object):Object, что даст вам возможность фильтровать детей первого уровня, а также возможность вызывать отфильтрованный метод для дочерних элементов на любой n-й уровень.

Class MyCollection extends HierarchicalData 
{ 
    override public function getChildren(node:Object):Object 
    { 
    if (node is a VoTask) 
     (node.children as ArrayCollection).filterFunction = tasksFilterFunction; 
     node.children.refresh(); 
    else if (node is a Task) 
     (node.children as ArrayCollection).filterFunction = tasksFilterFunction; 
     node.children.refresh(); 
    // You can also write a more complex process of filtering. 

    return node; 
    } 
}