PDA

Просмотр полной версии : List + ItemRenderer = полная неразбериха.


Astraport
17.10.2011, 13:53
Компонент Spark List использует для вывода данных кастомный ItemRenderer, а в качестве DataProvider - ArrayCollection. В Itemrenderer передается несколько параметров и на их основе выводятся данные.
В Листе все выводится правильно. Но обращение к data.myParams в итемрендерере по Creation Complite выводит полную ерунду - данные путаются, сдвигаются по позициям. При этом ДатаПровайдер остается неизменным.
Десять раз все перепроверил.
Подскажите, плиз, где искать ошибку?

trng
17.10.2011, 14:17
Что за элементы в ArrayCollection?

Astraport
17.10.2011, 14:28
Объекты с разными свойствами.

Добавлено через 5 минут
Ещё добавлю. Вообще элементов в массиве 8, выводится в листе 8 объектов, а creation complite вызывается только 7 раз.

trng
17.10.2011, 14:43
для начала посмотрите что у вас попадает в itemrenderer:

protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void{
var s:String = ' ';
for (var prop in data)
s += prop + '=' + data[prop] + ' ; ';
trace('type: ', typeof data, s);
}

Astraport
17.10.2011, 14:44
В общем нашел решение проблемы. Нужно оверрайдить данные в итем рендерер.
Примерно так:
override public function set data(value:Object):void {
if(value != null) {
super.data = value;
//тут определить все нужные данные
}
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}

Добавлено через 1 минуту
trng, спасибо.
Я все это уже смотрел. Ерунда полная выводилась. Решение выше.

trng
17.10.2011, 14:51
Ясно. Был включен useVirtualLayout?

Astraport
17.10.2011, 15:15
Нет, не был.

billion
18.10.2011, 08:45
Столкнулся с такой же проблемой.... список ведёт себя нормально, но вот его Items прыгают куда хотят... помогите прикрутить данный код плиз.... это надо отдельный класс создавать для ItemRenderer? у меня щас всё через компоненты mxml работает

Astraport
18.10.2011, 11:22
Пихайте код из сообщения № 5 в MXML реализующий ваш ItemRenderer.
Ну или приводите свой код.

billion
18.10.2011, 12:25
как-то странно себя ведёт эта штуковина.... то глючит, то не глючит....

кстати код на 450 строк.... пока не оптимизировал....попробую сначала воспроизвести последовательность при которой Итемсы скачут кто-куда.... если не удастся решить проблему, выложу код сюда

Astraport
18.10.2011, 12:34
кстати код на 450 строк....
Это в итемрендерере столько? Все не нужно, лишнее можно вырезать и вставить сюда.

billion
18.10.2011, 13:37
ага.... удалось выяснить следующее:

List у меня внутри TitleWindow рамером 200 px.
1. В List вывожу 5 элементов. Отображаются нормально. Ещё на 2 элемента хватило бы места (111.jpg).

2. Нажимаю на первый элемент - отображается RichEditableText с отображением категорий (222.jpg)
за фоном подгружаются данные из БД. Нажимаю на второй элемент - тоже всё хорошо, данные из БД.

3. Спускаюсь вниз списка и выбираю последний элемент - отображаются категории первого элемента. Подгрузки из БД не происходит. Собственно вот он глюк. (333.jpg)

Но! Если окошко сделать большего размера чтобы скролла не было и места хватало для прорисовывания каждого элемента - то глюков никаких нет. Экспериментально выяснил если высоту окна сделать -10 или +10 то глюка нет.

что это? глюк? у меня подозрение что что-то в коде у меня не так.

В ItemRenderer примерно следующий код:

<s:Label id="labelDisplay"
text="{data.label}"
left="10" top="3"
textAlign="start"
fontWeight="bold"
verticalAlign="middle"
maxDisplayedLines="3"/>
</s:Group>

<s:BorderContainer id="bc" includeIn="selected" >
<s:VGroup id="vg" width="100%" height="100%" top="0">

<s:RichEditableText id="ta0" heightInLines="{NaN}"
creationComplete="ta0_creationCompleteHandler(event)" />
</s:VGroup>
</s:BorderContainer>




protected function ta0_creationCompleteHandler(event:FlexEvent):void
{

//делаю загрузку данных из БД

var s:String = new String();
for (var i:Number=0;i<cr_ob_sf.lastResult.length;i++) {
s += '<a id="'+cr_ob_sf.lastResult[i].P+'">'+cr_ob_sf.lastResult[i].A+'</a> '
}
var cfg:Configuration = TextFlow.defaultConfiguration;
var normalFmt:TextLayoutFormat = new TextLayoutFormat(cfg.defaultLinkNormalFormat);
normalFmt.color = 0x0000FF;
normalFmt.textDecoration = TextDecoration.UNDERLINE;
var hoverFmt:TextLayoutFormat = new TextLayoutFormat(cfg.defaultLinkHoverFormat);
hoverFmt.color = 0x0000FF;
hoverFmt.textDecoration = TextDecoration.UNDERLINE;
cfg.defaultLinkNormalFormat = normalFmt;
cfg.defaultLinkHoverFormat = hoverFmt;
ta0.textFlow = TextConverter.importToFlow(s, TextConverter.TEXT_FIELD_HTML_FORMAT, cfg);

ta0.validateNow();

}

GBee
18.10.2011, 14:37
ItemRendererов создается ровно столько, сколько влезает. При скролинге у существующих обновляется data.
Поэтому вешать что-то отвечающее за вывод данных в creationComplete бессмысленно. override data, как сказал Астрапорт.

Добавлено через 5 минут
Вынесите запрос из итемРендерера, по change листа например его делайте, и только в том случае, если нет данных. Полученное пихайте в нужный элемент датапровайдера. Иначе у вас получится/получается - выбрал элемент - запрос - скролл - ответ и в итемрендерере с новыми данными появляется ранее запрошенная инфа для другого элемента.

billion
18.10.2011, 15:29
ага.... вот теперь понятно.... благодарю за ответ. придётся выносить все лоадеры за итемрендеры. вот только с override data не понятно.... как этот код прикрутить и куда? можно примерчик?

GBee
18.10.2011, 15:32
В код итемрендерера, почитайт хелп, это сеттер в него приходит объект из вашего датаПровайдера, от него и пляшите. List.selectedItem это тот же объект.