Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   ItemRender & RadioButton (http://www.flasher.ru/forum/showthread.php?t=147279)

Freedom77 30.11.2010 23:32

ItemRender & RadioButton
 
В ItemRender отображается своя компонента содержащая Radiobutton. Как при выборе одного из них, отключить ранее выбранный radiobutton? Пытался из компоненты добраться хотябы до функции сброса всех предыдущих путём outerDocument.MyFunction, но это не срабаывает. Ругается что не может вызвать MyFunction ещё при компиляции.

ShockWave512 01.12.2010 01:17

parent.MyFunction

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

2 вариант
статическое поле типа булеан в классе рендера, на него биндишь состояние всех экземпляров рендера, в кликнутом рендере игноришь состояние этого поля ( поле -> false )

alatar 01.12.2010 11:30

Первый вариант тормознутый, второй вызовет проблемы при скроллинге.
Как вариант – использовать первый предложенный вариант, но при этом в родителе добавить поле для хранения ссылки на выбранный в данный момент элемент. При новом клике выключать текущий и включать новый. При этом надо убедиться, что RadioButton не попали в одну группу, а то проблем не оберетесь.
В идеале, лучше использовать кнопки, которые выглядят как RadioButton, а состояние менять в данных. Сама кнопка при этом слушает изменения свойств в своем data и при изменениях меняет свой вид.

Волгоградец 01.12.2010 11:50

Для датагрида я использую такой рендерер
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:MXDataGridItemRenderer 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:controls="radiobutton.*"
                                                  focusEnabled="true"
                                                  creationComplete="init()">
        <fx:Script>
                <![CDATA[
                        import mx.controls.DataGrid;
 
                        [Bindable]
                        public var master:DataGrid;
 
                        override public function set data(value:Object):void
                        {
                                super.data = value;
                        }
 
                        private function init():void
                        {
                                master = owner as DataGrid;
                        }
                ]]>
        </fx:Script>
 
        <controls:RadioButton verticalCenter="0" left="2" id="rbData" selected="{master.selectedItem == data}"/>
 
</s:MXDataGridItemRenderer>

Это то же самое, что alatar советует, только не кастомные кнопки юзаются, а именно радио кнопка меняет свое состояние слушая data.

alatar 01.12.2010 11:59

Просто для такого функционала в RadioButton много лишнего.

Freedom77 01.12.2010 15:24

alatar, Волгоградец: мне даже проще изменить в самих данных. Данные хранятся в виде массива. Но при клике на радиокнопку, обрабатывается только скрипт относящийся к самой строке на которой он находится. А как обнолуить данные во всем массиве, находясь в в ItemRender? Ведь ItemRender описывает каким будет поле, и дублирует их по количеству строк (грубо говоря).

Добавлено через 2 минуты
В примере Волгоградец немогу понять где происходит обнуление. Насколько я понял он получает данные, и в зависимости от него выводит данные, точне отображает выбрана ли кнопка или нет. Поправьте если я не прав.

alatar 01.12.2010 15:32

Обнуление будет происходить в наследнике DataGrid (List или в чем там у вас используется этот итем-рендерер), или в outerDocument, по клику на итеме (или по любому событию, которое вам приглянется).

Freedom77 01.12.2010 22:13

Пробую какраз через outerDocument.MyFunction, но говорит что функция MyFunction не существует.
P.S.: ItemReader, точнее компоненты расположенные в ItemRender идут как отдельная компонента. Может ли это влиять?

alatar 01.12.2010 22:45

Покажите код.

Freedom77 02.12.2010 10:16

Немного изменил код, теперь не ругается, но и не сбрасывается. Вот код:
Переменной Otv передаётся массив с данными.
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:Scroller xmlns:fx="http://ns.adobe.com/mxml/2009"
                        xmlns:s="library://ns.adobe.com/flex/spark"
                        xmlns:mx="library://ns.adobe.com/flex/mx" height="100%" width="100%">
 
        <fx:Script>
                <![CDATA[
                        import mx.collections.ArrayCollection;
                        public var Otv:ArrayCollection;
                        public function Radio_selected(): ArrayCollection
                        {  var i:int;
 
                                for (i=1; i< Otv.length; i++ )                               
                                {
                                        Otv[i].selected=false;
 
                                }
 
                                return Otv;
 
 
                        }
                ]]>
        </fx:Script>
 
 
        <s:DataGroup height="100%" left="0" right="40" top="0" id="dg"  verticalScrollPosition="50" dataProvider="{Otv}" >
        <s:layout>
                <s:VerticalLayout gap="0" useVirtualLayout="true"/>
        </s:layout>
        <s:itemRenderer>
                <fx:Component>
                        <s:ItemRenderer>
                                <fx:Script>
                                        <![CDATA[
                                                import spark.events.IndexChangeEvent;
 
 
 
                                                override public function set data(value:Object):void {
                                                        super.data = value;
 
                                                        if (data == null) // a renderer's data is set to null when it goes out of view
                                                                return;
 
 
                                                        if (data.selected==true) {radio.selected=true;} else {radio.selected=false;}
                                                }
 
 
                                                protected function otvet_changeHandler(event:Event):void
                                                {
                                                        data.txt=otvet.text;
                                                }
 
 
 
                                                protected function radio_changeHandler(event:Event):void
                                                {
                                                        outerDocument.Radio_selected();
                                                        data.selected=true;
 
                                                }
 
                                                protected function dropdownlist1_changeHandler(event:IndexChangeEvent):void
                                                {
                                                        viewstack.selectedChild=type.selectedItem.type;
                                                }
 
                                        ]]>
                                </fx:Script>
 
 
                                <s:BorderContainer cornerRadius="7" left="10" right="10" height="111" width="600" top="5" bottom="5" id="border">
                                        <s:RadioButton x="10" id="radio" verticalCenter="0" change="radio_changeHandler(event)"/>
                                        <s:DropDownList x="64" y="10" id="type" change="dropdownlist1_changeHandler(event)" selectedIndex="0">                                                       
                                                <s:dataProvider>
                                                        <mx:ArrayList>
                                                                <fx:Object label="Текст" type="{text}" />
                                                                <fx:Object label="Рисунок" type="{image}" />
                                                        </mx:ArrayList>
                                                </s:dataProvider>
                                        </s:DropDownList>
                                        <s:Label x="30" y="16" text="Тип:"/>
                                        <mx:ViewStack x="29" y="8" id="viewstack" width="526" height="93">
                                                <s:NavigatorContent id="text" width="100%" height="100%" >
                                                        <s:TextInput x="10" y="37" width="506" id="otvet" text="{data.txt}" change="otvet_changeHandler(event)"/>
                                                </s:NavigatorContent>
                                                <s:NavigatorContent id="image" width="100%" height="100%">
                                                </s:NavigatorContent>
                                        </mx:ViewStack>
 
                                </s:BorderContainer>
 
                        </s:ItemRenderer>
                </fx:Component>
        </s:itemRenderer>
</s:DataGroup>
</s:Scroller>


alatar 02.12.2010 12:08

Естественно не сбрасывается, как ItemRenderer узнает, что свойство selected непонятно в чем поменялось? Объект который находится в массиве должен послать событие, что свойство изменилось. В сеттере data надо подписаться на это событие (предварительно отписавшись, если data уже было установлено ранее), при наступленни этого события надо опять проверить свойство selected.
P.S. Свойства и методы принято называть с маленькой буквы.

Добавлено через 3 минуты
Для вашего Otv сделайте геттер и сеттер. В сеттере передавайте ваш Otv в dataProvider DataGroup или поставьте для Otv метатег:
Код:

[Bindable]

Freedom77 02.12.2010 13:56

С [Bindable] действительно что то ступил.
Теперь все работает, но ранее выбранные пункты отключаются при скролинге (перерисовке видимо).
Можно вылечить? Возможно ответ был дан уже выше, но чё то я не понял с геттер и сеттер?

alatar 02.12.2010 14:07

Забейте вы на этот RadioButton, он вам нафиг не нужен (при создании он пытается добавиться в группу, чем создает проблемы в рендерерах). Возьмите ToggleButton, сделайте ей скин на основе RadioButtonSkin и все заработает как часы.


Часовой пояс GMT +4, время: 01:54.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.