【问题标题】:How to handle a change in a custom GridItemRenderer如何处理自定义 GridItemRenderer 中的更改
【发布时间】:2013-03-18 00:39:46
【问题描述】:

我在我的一个项目中使用DataGrid,其中一个列使用自定义ItemRenderer 以将布尔值表示为CheckBox

<s:DataGrid id="clients" resizableColumns="false">
    <s:columns>
        <s:ArrayList>
            <s:GridColumn dataField="fullName" headerText="Client name" />
            <s:GridColumn dataField="active" headerText="Active?" width="90"
                          itemRenderer="CheckBoxGridItemRenderer"/>
        </s:ArrayList>
    </s:columns>
</s:DataGrid>

这里是CheckBoxGridItemRenderer的代码:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx"
                    clipAndEnableScrolling="true">

    <fx:Script>
        <![CDATA[
            override public function prepare(hasBeenRecycled:Boolean):void {
                checkBox.selected = Boolean(data[column.dataField]);
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="checkBox" horizontalCenter="0" />

</s:GridItemRenderer>

现在这是我的问题:处理我声明为 DataGrid 的类中的数据更改的最佳方法是什么?

我尝试在我的自定义项渲染器类中更改数据值:

private function valueChange():void
{
    data.active = checkBox.selected;
}

[...]

<s:CheckBox id="checkBox" change="valueChange()" />

然后在 DataGrid 的 dataProvider 上收听 CollectionEvent.COLLECTION_CHANGE 事件,但我从不处理任何更改。有什么想法或建议吗?

【问题讨论】:

  • 那么,您想从 DataGrid 中更改数据吗?尝试将rendererIsEditable="true" 添加到列中。
  • 这不会改变任何东西。仅供参考,我已经能够在没有它的情况下更改 CheckBox 值。但我想在我的 ItemRenderer 之外处理相关事件,即在 DataGrid 被实例化的类中

标签: actionscript-3 apache-flex datagrid event-handling dataprovider


【解决方案1】:

您在哪里更改数据。当数据集合的元素发生更改时,除非您为数据集合调度 CollectionEvent.COLLECTION_CHANGE,否则 DataGrid 无法检测到任何内容。 另外,数据集合应该是ArrayCollection,而不是Array。

【讨论】:

  • DataGrid的dataProvider设置在代码的别处,是一个ArrayCollection,不过这跟我的问题无关。
  • CollectionEvent.COLLECTION_CHANGE 必须分派给数据提供者,否则 valueChanged() 将永远不会运行。
  • 如果您谈论我在自定义ItemRenderer 中添加的valueChange() 方法,则每当我单击CheckBox 时都会成功调用此方法
  • 对不起,我犯了错误。尝试覆盖 set data 函数而不是 prepare。不要忘记调用 super.data。
  • 我需要覆盖 prepare 以便将正确的初始值从数据源分配给我的复选框。另一方面,除了调用super 方法之外,我在覆盖set data 时没有任何事情可做。也许我的问题还不够清楚。我发布了一个可能有助于澄清它的答案
【解决方案2】:

当我找到解决问题的方法后,我将在此处发布,但我将问题留待一段时间,以防有人提出更好的问题。

首先我创建了一个CustomEvent(我可以使用CollectionEvent 类,但这样我确信我不会弄乱DataGrid 的内部逻辑)

package
{
    import flash.events.Event;

    public class CustomEvent extends Event
    {
        public static const CHANGE:String = "change";

        public var column:String;
        public var data:Object;

        public function CustomEvent(column:String, data:Object)
        {
            super(CHANGE, true);
            this.column = column;
            this.data = data;
        }
    }
}

注意对super() 的调用,bubbles 设置为 true。这实际上是在此处处理事件所必需的。

然后我修改了我的CheckBoxGridItemRenderer 以在选中/取消选中复选框时调度此事件:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark" 
                    xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true">

    <fx:Script>
        <![CDATA[
            import CustomEvent;

            override public function prepare(hasBeenRecycled:Boolean):void {
                if (data)
                {
                    checkBox.selected = Boolean(data[column.dataField]);
                }
            }

            private function valueChange():void
            {
                data[column.dataField] = checkBox.selected;
                dispatchEvent(new CustomEvent(column.dataField, data));
            }
        ]]>
    </fx:Script>

    <s:CheckBox id="checkBox" horizontalCenter="0" change="valueChange()" />
</s:GridItemRenderer>

最后我只需要监听DataGrid 实例调度的自定义事件:

clients.addEventListener(CustomEvent.CHANGE, handleCustomEvent);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多