|
|
|||||
Вложенные итемРендереры
Я надеюсь что здесь ещё пишут на Флексе)
У меня List со сложным итемрендерером, внутри которого ещё два итемрендерера. Постоянно происходит путаница данных, потому что датапровайдер внутренних итемрендереров создается налету из первого итемрендерера. Мне что в корневом классе создавать Vector.<ArrayCollection> для всех вложенных данных?
__________________
In Code We Trust |
|
|||||
Интересно, тут ещё остались специалисты по Флексу?
Похоже окончательно технология загнулась... Ну да ладно, просто мучаюсь который день и никак не найду приемлемого решения. Никак не разберусь как правильно организовать данные. Итак вот есть драгабл List [Bindable] public static var posts:ArrayCollection = new ArrayCollection(); [Bindable] private var dragit:Boolean = false; protected function lst_itemClickHandler(evt:ItemClickEvent):void { if (evt.label == 'mousedown') { dragit = false; return; } if (evt.label == 'mouseup') { dragit = true; return; } } <s:List id="list" width="100%" height="100%" dataProvider="{posts}" itemRenderer="postIR" selectedIndex="0" dragEnabled="{dragit}" dragMoveEnabled="true" dropEnabled="true" useVirtualLayout="false"/> Вот postIR <?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:c="*" autoDrawBackground="true" creationComplete="itemrenderer1_creationCompleteHandler(event)" maxHeight="120"> <fx:Script> <![CDATA[ [Bindable] private var index:int; [Bindable] private var socDP:ArrayCollection; protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void { index = ((this.owner as List).dataProvider as ArrayCollection).getItemIndex(data); socDP = Copypaste.socialVector[index] as ArrayCollection; soc.addEventListener(ItemClickEvent.ITEM_CLICK, soc_itemClickHandler); } //Deleted some code ]]> </fx:Script> <c:CheckList id="soc" width="100%" height="100%" itemRenderer="socIR" mouseDown="txt_mouseDownHandler(event)" mouseUp="soc_mouseUpHandler(event)" dataProvider="{socDP}" allowMultipleSelection="true" useVirtualLayout="false" click="soc_clickHandler(event)"> <c:layout> <s:TileLayout requestedColumnCount="3" verticalAlign="top" padding="5"/> </c:layout> </c:CheckList> //Deleted some code </s:ItemRenderer> <?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" autoDrawBackground="true" click="itemrenderer1_clickHandler(event)" creationComplete="itemrenderer1_creationCompleteHandler(event)"> <s:layout> <s:HorizontalLayout verticalAlign="middle" padding="5"/> </s:layout> <s:states> <s:State name="normal"/> <s:State name="selected"/> </s:states> <fx:Script> <![CDATA[ protected function itemrenderer1_clickHandler(event:MouseEvent):void { if (this.selected) { data.selected = true; } else { data.selected = false; } var parentList:List = owner as List; var e:ItemClickEvent = new ItemClickEvent(ItemClickEvent.ITEM_CLICK, true); e.item = data; e.index = parentList.dataProvider.getItemIndex(data); e.label = "selected"; dispatchEvent(e); } override public function set data(value:Object):void { super.data = value; if (value.selected) { data.selected = true; } else { data.selected = false; } } protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void { if (data.selected) { this.selected = true; } else { this.selected = false; } } ]]> </fx:Script> <s:CheckBox id="socCheck" selected.selected="true" selected.normal="false" mouseEnabled="false"/> <s:Image source="{'images/socialicons/' + data.icon}"/> <s:Label text="{data.label}"/> </s:ItemRenderer> Неужели нет какой-то стройной системы для организации правильной иерархии данных? Я пробовал в data первого итемрендерера передавать объект или ArrayCollection, но это выдает ошибки или не работает. В общем нужен любой совет или даже доработка за деньги.
__________________
In Code We Trust |
|
|||||
Не очень понятно, как данные организованы.
В posts по идее должны хранится объекты, у каждого из которых есть какой-то массив socialVector. То есть я бы создал класс Post, который содержит массив соцсетей. Массив posts отдаем внешнему листу, в сеттере data postIR отдаем локальному листу этот data.socialVector как датапровайдер. Дальше все должно вроде и так работать. itemrenderer1_creationCompleteHandler - выкинуть
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку. |
|
|||||
GBee, привет дружище)
Проблема в том, что рендеры пересоздаются. Да, можно хранить во внешних классах, но при перетаскивании ещё и индексы меняются и все это нужно учитывать. Все путается у меня постоянно. Я думал может есть какие-то встроенное решение, у Флекса куча разных возможностей и свойств, но похоже придется топорно городить огород. Добавлено через 2 часа 25 минут Цитата:
У меня есть объект PostData который является элементом датапровайдера для главного List: package { import flash.events.EventDispatcher; import mx.collections.ArrayCollection; [Bindable] public class PostData extends EventDispatcher { public var sort:int; public var uid:String; public var text:String; public var image:String; public var url:String; public var socials:Vector.<int>; public var res:Vector.<int>; public var resources:ArrayCollection; public var tags:String; public var published:Boolean; } } К resources привязываю другой ArrayCollection, который имеет данными такой объект: ackage { import flash.events.EventDispatcher; [Bindable] public class ResData extends EventDispatcher { public var uid:String; public var name:String; public var url:String; public var social:int; public var tags:String; public var mintags:int; public var maxtags:int; public var selected:Boolean; } } Теперь как связать выделение с данными? Если кликаю по итему, то я назначаю внутри его: Если так не назначать, то при драге все выделения слетают. Если так назначать, то при драге выделение не слетают, но при выделении например первого итема все первые итемы в остальных рендерах тоже выделяются. И вот как от этого избавиться непонятно.
__________________
In Code We Trust Последний раз редактировалось Astraport; 27.04.2016 в 22:25. |
|
|||||
Привет!
В свое время мне очень помогла фраза "Рендереров не существует". :о)) Все дело в данных. Я со спарком не работал, но думаю там в этом плане не сильно должно отличаться. 1) Показываем инфу. Из PostIR навсегда выкидываем itemrenderer1_creationCompleteHandler(event:FlexEvent):void Дальше можно через сеттер data, либо биндингом. Так как по идее в PostIR в дату приходит PostData, то можно сразу забиндить socIR в данном случае вообще тупой как дрова. Так же данные (ResData) либо через сеттер получаем, либо биндим (как частично уже сделано с лейблом и картинкой) selected.selected="true" selected.normal="false" пока в мусорку Код весь тоже удаляем - оставляем один мхмл. Стейты - тоже Тестим отображение и перетаскивание!! Добавлено через 3 минуты override public function set data(value:Object):void { super.data = value; if (value.selected) { data.selected = true; } else { data.selected = false; } } Тут смешной парадокс :о)) в value приходит ResData, которая сразу попадает в data , ну а дальше сам понимаешь :о)) Добавлено через 20 минут Изменение чекбоксов и дополнение отображения. Тут все по идее просто и делается в postIR 1) Подписываемся на CHANGE у c:CheckList (Это стандартный компонент? Если нет, то лучше пока на обычный поменять лист) в обработчике пробегаем по data.resources и всем selected = false; потом бежим по массиву event.currentTarget.selectedItems каждому ему (ResData) selected = true; Вроде должно работать. И насчет отображения первоначального забыл. Все-таки чтобы чекбоксы не только отмечались, но и выделялись как выбранные элементы списка. Идем в postIR 1) Создаем переменную например 2) прикручиываем к <c:CheckList id="soc" dataProvider="{data.resources}" selectedItems="{_selectedResData}" .../>. в нем, если дата пришла - создаем массивчик, бежим по дата.ресурсес и пихаем в новый массивчик РесДаты у которых селектед = труе. И после пихаем указатель массивчика в _selectedResData. Его это будоражит, он генерит событие (или как там биндинг сделан) И выделяет нужные чекбоксы. Короче, вот так, но это самый простой путь, который я не очень люблю. Биндинг удобен, но как-то не по нраву мне. А ну и я бы повесил биндинг на конкретные поля, которые будем использовать для отображения в итем рендерерах. Но тут не знаю, что лучше. ackage { import flash.events.EventDispatcher; public class ResData extends EventDispatcher { public var uid:String; [Bindable] public var name:String; [Bindable] public var url:String; public var social:int; public var tags:String; public var mintags:int; public var maxtags:int; [Bindable] public var selected:Boolean; } } package { import flash.events.EventDispatcher; import mx.collections.ArrayCollection; public class PostData extends EventDispatcher { public var sort:int; public var uid:String; [Bindable] public var text:String; public var image:String; public var url:String; public var socials:Vector.<int>; public var res:Vector.<int>; [Bindable] public var resources:ArrayCollection; public var tags:String; public var published:Boolean; } }
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку. Последний раз редактировалось GBee; 28.04.2016 в 00:53. |
Часовой пояс GMT +4, время: 14:38. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|