DataGrid ItemRenderer Ошибка - PullRequest
       19

DataGrid ItemRenderer Ошибка

1 голос
/ 25 августа 2011

Я заполняю 3 столбца моей таблицы данных, используя простой файл XML.Предполагается, что последний столбец - это itemrenderer, в основном Button.Однако кнопка должна появляться только в определенных строках 3-го столбца таблицы данных, в зависимости от значения в файле XML, которое имеет значение «true» или «false».Поэтому в основном я хочу установить для свойства Visible кнопки в itemrenderer значение true или false.

    Here is the whole application

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                   xmlns:s="library://ns.adobe.com/flex/spark" 
                   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" pageTitle="Dynamic Data Grid">
        <!--    <s:layout>
        <s:VerticalLayout horizontalAlign="center"/>
        </s:layout>-->

        <fx:Declarations>
            <s:ArrayList id="cccb_dp">
                <fx:String>User1</fx:String>
                <fx:String>User2</fx:String>
                <fx:String>User3</fx:String>
            </s:ArrayList>

            <fx:XML id="tempXML" source="assets/fieldsXML.xml"/>
            <s:XMLListCollection id="fieldsXMLList" source="{tempXML.worker}"/>

        </fx:Declarations>

        <s:layout>
            <s:VerticalLayout/>
        </s:layout>

        <s:VGroup verticalAlign="middle" horizontalCenter="1" verticalCenter="1" horizontalAlign="center">

            <s:HGroup horizontalAlign="center" verticalCenter="-221" width="580" height="158" x="75">
                <s:Label text="CC" width="23" height="24" verticalAlign="middle" fontWeight="bold"/>
                <s:DropDownList id="cc_cb" dataProvider="{cccb_dp}" width="175"/>
            </s:HGroup>

            <mx:DataGrid id="myDG" dataProvider="{fieldsXMLList}">
                <mx:columns>
                    <mx:DataGridColumn headerText="Header1" dataField="@field_label"/>
                    <mx:DataGridColumn headerText="Header2" dataField="@field_value"/>
                    <mx:DataGridColumn headerText="Header3">
                        <mx:itemRenderer>
                            <fx:Component>
                                <s:Button click="onClick(event)" label="Click Me" dataChange="onDataChange(event)" >
                                    <fx:Script>
                                        <![CDATA[
                                            import mx.controls.Alert;

                                            private function onClick(evt:Event):void
                                            {
                                                Alert.show(data.@field_visibility);
                                            }
                                            private function onDataChange(evt:Event):void
                                            {
                                                visible=data.@field_visibility;
                                            }
                                        ]]>
                                    </fx:Script>
                                </s:Button>
                            </fx:Component>
                        </mx:itemRenderer>
                    </mx:DataGridColumn>
                </mx:columns>
            </mx:DataGrid>

        </s:VGroup>

    </s:Application>


    The XML:
    <worker_fields>
        <worker id="1" field_label="Seller" field_value="5" field_visibility="false"/>
        <worker id="1" field_label="Balance" field_value="100" field_visibility="true"/>
        <worker id="1" field_label="Cash Owned" field_value="300" field_visibility="true"/>

        <worker id="2" field_label="Seller" field_value="5" field_visibility="false"/>
        <worker id="2" field_label="Balance" field_value="130" field_visibility="true"/>
        <worker id="2" field_label="Cash Owned" field_value="132" field_visibility="false"/>
        <worker id="2" field_label="Credits" field_value="131" field_visibility="true"/>
    </worker_fields>    


Any idea how to go around it.  

Thanks you for the precious help.

Ответы [ 2 ]

2 голосов
/ 25 августа 2011

Каждый itemRenderer получает объект данных; который содержит элемент, который отображает средство визуализации. В рендере не будет свойства с именем field_visibility, потому что оно не является свойством по умолчанию и вы его не создали.

Однако это должно быть свойство объекта данных, передаваемого в средство визуализации.

Свойство data должно указывать на одного работника:

<worker id="1" field_label="Cash Owned" field_value="300" field_visibility="true"/>

И у вас должна быть возможность доступа к нему с небольшими изменениями в вашем коде:

        <mx:itemRenderer>
            <fx:Component>
                <mx:Button click="onClick(event)" label="Click Me" visible="{data.@field_visibility}">
                    <fx:Script>
                    <![CDATA[
                        import mx.controls.Alert;

                        private function onClick(evt:Event):void
                        {
                            Alert.show(data.field_visibility);
                        }
                    ]]>
                    </fx:Script>
                </mx:Button>
            </fx:Component>
        </mx:itemRenderer>

Для достижения наилучших результатов; вам следует рассмотреть возможность прослушивания события изменения данных и изменения видимости таким образом. Известно, что это вызывает меньше проблем в долгосрочной перспективе, чем использование привязки:

        <mx:itemRenderer>
            <fx:Component>
                <mx:Button click="onClick(event)" label="Click Me" dataChange="onDataChange()" >
                    <fx:Script>
                    <![CDATA[
                        import mx.controls.Alert;

                        private function onClick(evt:Event):void
                        {
                            Alert.show(data.field_visibility);
                        }
                        private function onDataChange(evt:Event):void
                        {
                            visible=data.@field_visibility";
                        }
                    ]]>
                    </fx:Script>
                </mx:Button>
            </fx:Component>
        </mx:itemRenderer>

По какой-то причине оригинальное редактирование последнего кода уничтожило его актуальный вопрос. У Flex возникла проблема с преобразованием строкового значения XML в логическое значение. data.@field_visibility похоже возвращает XMLList. Как логическое значение, которое всегда будет истинным. Это вопрос один. Это можно решить, выполнив такое условие:

if(data.@field_visibility == "true"){
 this.button.visible = true;
} else {
 this.button.visible = false;
}

Вторая проблема заключается в том, что кнопка не исчезает, если она является компонентом верхнего уровня. Итак, вам нужно поместить его в контейнер. Я использовал холст.

Вот модифицированное приложение:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" pageTitle="Dynamic Data Grid">
    <!--    <s:layout>
    <s:VerticalLayout horizontalAlign="center"/>
    </s:layout>-->

    <fx:Declarations>
        <s:ArrayList id="cccb_dp">
            <fx:String>User1</fx:String>
            <fx:String>User2</fx:String>
            <fx:String>User3</fx:String>
        </s:ArrayList>

        <fx:XML id="tempXML" source="assets/fieldsXML.xml"/>
        <s:XMLListCollection id="fieldsXMLList" source="{tempXML.worker}"/>

    </fx:Declarations>

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:VGroup verticalAlign="middle" horizontalCenter="1" verticalCenter="1" horizontalAlign="center">

        <s:Button click="{myDG.invalidateList()}" label="Invalidate List" />
        <s:HGroup horizontalAlign="center" verticalCenter="-221" width="580" height="158" x="75">
            <s:Label text="CC" width="23" height="24" verticalAlign="middle" fontWeight="bold"/>
            <s:DropDownList id="cc_cb" dataProvider="{cccb_dp}" width="175"/>
        </s:HGroup>

        <mx:DataGrid id="myDG" dataProvider="{fieldsXMLList}">
            <mx:columns>
                <mx:DataGridColumn headerText="Header1" dataField="@field_label"/>
                <mx:DataGridColumn headerText="Header2" dataField="@field_value"/>
                <mx:DataGridColumn headerText="Header3">
                    <mx:itemRenderer>
                        <fx:Component>
                            <mx:Canvas dataChange="container1_dataChangeHandler(event)" >
                                <mx:Button label="Click Me" id="button"  />
                                <fx:Script>
                                    <![CDATA[
                                        import mx.events.FlexEvent;

                                        protected function container1_dataChangeHandler(event:FlexEvent):void
                                        {
                                            if(data.@field_visibility == "true"){
                                                this.button.visible = true;
                                            } else {
                                                this.button.visible = false;
                                            }
                                        }

                                    ]]>
                                </fx:Script>
                            </mx:Canvas>
                        </fx:Component>
                    </mx:itemRenderer>
                </mx:DataGridColumn>
            </mx:columns>
        </mx:DataGrid>

    </s:VGroup>

</s:Application>
0 голосов
/ 25 августа 2011

В дополнение к ответу @ www.Flextras.com.

Если вы хотите положиться на свойство dataField вашего столбца и сделать свой рендеринг независимым от данных, вы можете реализовать интерфейс mx.controls.listClasses.IDropInListItemRenderer в вашем рендерере. Насколько вы унаследовали от MX Button, который уже реализовал его, код будет следующим:

<mx:DataGrid dataProvider="{fieldsXMLList}" id="myDG">
    <mx:columns>
        <mx:DataGridColumn dataField="@field_label" headerText="Header1" />
        <mx:DataGridColumn dataField="@field_value" headerText="Header2" />
        <mx:DataGridColumn dataField="@field_visibility" headerText="Header3">
            <mx:itemRenderer>
                <fx:Component>
                    <mx:Button click="onClick(event)" label="Click Me" visible="{data[listData.dataField]}">
                        <fx:Script>
                        <![CDATA[
                            import mx.controls.Alert;

                            private function onClick(evt:Event):void
                            {
                                Alert.show(data[listData.dataField]);
                            }
                        ]]>
                        </fx:Script>
                    </mx:Button>
                </fx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
    </mx:columns>
</mx:DataGrid>
...