【问题标题】:Cache variables in dataprovider在数据提供者中缓存变量
【发布时间】:2012-01-05 13:32:15
【问题描述】:

我有一个模型类,其中包含一组经常变化的数字变量。 它们都调度自定义事件,因此是可绑定的。

在我的 UI 中,其中一些类实例被捆绑到一个 ArrayList 中,该 ArrayList 用作 Spark DataGrid 的数据提供者。 类变量的变化非常好,所以问题出现了。

我现在想做的是根据传入的数据更改这些数字的颜色格式(确切地说是网格列中的相应标签),也就是说,当新值是大,当新值小于旧值时变为红色。

我怎样才能做到这一点?我想对旧值进行某种缓存,然后比较旧值和新值。 这是这样做的方法吗,如果是这样,怎么做?还是有另一种可能更简单的方法而无需缓存任何东西?

任何帮助将不胜感激!

编辑: 根据@NoobsArePeople2 给出的示例,这是我当前的代码。 首先是数据网格。 dataProvider 是一个包含 myModel 类对象的 ArrayList。

<s:DataGrid dataProvider="{_listItems}" >
    <s:columns>
        <s:ArrayList>
        <s:GridColumn dataField="change" headerText="Change" itemRenderer="tableCell">
        <s:GridColumn dataField="bid" headerText="Bid" itemRenderer="tableCell">
  ...
</s:DataGrid>

现在是 tableCell 渲染器;

<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%">

<fx:Script>
    <![CDATA[
        private var previousData:Number;
        private var labelColor:uint;
                    private var _data:Object;

        override public function set data(value:Object):void {

            previousData = _data;
            _data = Number(value);
            invalidateProperties();
        }

        override protected function commitProperties():void {
            super.commitProperties();

            if(previousData < data) {
                labelColor = 0x40c040;
            } else if (previousData > data){
                labelColor = 0xf05050;
            } else
                labelColor = 0xc0c0c0;

            itemLabel.setStyle("color", labelColor);
            itemLabel.text = String(_data); 
        }   
    ]]>
</fx:Script>

<s:Label id="itemLabel"/>
</s:GridItemRenderer>

到目前为止,这工作正常(与使用引发未定义错误的数据属性相反),但是,当将这个项目渲染器用于多个网格列时,它对每个网格列使用相同的值。这是关于什么的?

编辑:对不起,这只有在我直接处理模型的属性时才有效,比如 data.property,这是我做不到的。我需要所有列的通用项目渲染器。

【问题讨论】:

    标签: apache-flex data-binding datagrid itemrenderer datagridcolumn


    【解决方案1】:

    要走的路是自定义项目渲染器。 item renderer 将附带一个data 属性(其中data 是来自您的数据提供者的单个值),当您的数据提供者在DataGrid 上发生更改时,将为您设置该属性。你会想要

    1. 添加一个新的私有变量previousData,类型为Object,并且
    2. 在您的项目渲染器中覆盖 data 的设置器。

    data 的设置器将如下所示:

    override public function set data(value:Object):void
    {
        // If the data hat not changed, don't do anything
        if (data == value) return;
    
        // Take the current data and store it in previousData
        previousData = data;
    
        // Update the current data to the new value that was passed in
        // BEGIN EDIT
        // data = value; <-- Previous code example is wrong it should be:
        super.data = value;
        // END EDIT
    
        // Tell Flex to update the properties of this renderer
        invalidateProperties();
    }
    

    然后,在您的项目渲染器中,像这样覆盖 commitProperties() 方法:

    override protected function commitProperties():void
    {
        super.commitProperties();
    
        // pseudo code follows
        if (previousData < data)
        {
            labelColor = green;
        }
        else if (previousData > data)
        {
            labelColor = red;
        }
        else
        {
            labelColor = black;
        }
    
        label.text = data;
        label.color = labelColor;
        // end pseudo code
    
    }
    

    或者,如果您需要访问 data 的属性并且不想硬编码值,这应该可以工作(注意:我还没有实际测试过这段代码,但它应该可以正常工作)。

    override protected function commitProperties():void
    {
        super.commitProperties();
    
        // This assumes your item renderer subclasses [GridItemRenderer][2]
        var dataField:String = column.dataField;
        var previousValue:Object = previousData[dataField];
        var currentValue:Object = data[dataField];
    
        // pseudo code follows
        if (previousValue < currentValue)
        {
            labelColor = green;
        }
        else if (previousValue > currentValue)
        {
            labelColor = red;
        }
        else
        {
            labelColor = black;
        }
    
        label.text = data;
        label.color = labelColor;
        // end pseudo code
    }
    

    【讨论】:

    • 谢谢@NoobsArePeople2 我明白你在这里做什么,基本上这正是我认为我需要的。但是,我对您的解决方案有一些小问题(在这里与我无关,我之前没有真正与 itemrenderers 合作过)。首先, if (data==value) 抛出一个“未定义”错误。其次,值对象将是 myModel 类型,即使相应 GridColumn 上的 dataField 设置为 myModel.change,它是一个 Number。我将我的渲染器(基于您的代码)添加到上面的初始问题中。
    • 那是因为我的代码示例有一个错误。查看以BEGIN EDIT开头的部分
    • 这里真的有点不对劲。即使我确实在没有项目渲染器的情况下在我的数据网格列中获得了正确的值(包括更新),但在项目渲染器中对转换为 Number 的值的简单跟踪总是在每次更新时输出 NaN,我真的不明白没有项目渲染器的数据网格中的列会显示正确的数字。
    • 在您的代码中,您要在_data 上设置值,您需要在data 上设置它。
    • 知道了。但是,这并不能解决我必须通过 data.propertyOfMyModel 访问 Number 值的问题,这意味着我必须为模型类具有的每个属性编写项目渲染器。我已经考虑过从项目渲染器内部访问 gridcoloum 中的数据字段,但似乎 spark 组件不支持。我真的迷路了。
    【解决方案2】:

    我认为您应该为您的数据网格创建自定义项渲染器。在那里,您应该覆盖 data 设置器并使用 BindingUtils 来处理字段更改。示例用法为here

    或者您可以通过以下方式在项目渲染器中重新分配数据:

    override public function set data(value:Object):void
    {
        if (value == data)
            return;
        myModelInstance = MyModelClass(value);
    }
    
    [Bindable]
    private var myModelInstance:MyModelClass;
    

    然后绑定到MXML项目渲染器中myModelInstance的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 2015-12-24
      • 1970-01-01
      • 2018-02-04
      • 2015-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多