在dataprovider中缓存变量

时间:2012-01-05 13:32:15

标签: flex data-binding datagrid itemrenderer datagridcolumn

我有一个模型类,其中包含一些经常更改的Number变量。 他们都调度他们的自定义事件,因此是可绑定的。

在我的UI中,一些类实例被捆绑到一个ArrayList中,该ArrayList用作Spark DataGrid的数据提供者。 类变量完全变好,所以问题就在那里。

我现在要做的是根据输入的数据更改这些数字的颜色格式(gridcooums中的相应标签是准确的),所以说当新值是绿色时改变绿色更大,当新值小于旧值时变为红色。

我该如何使这项工作?我虽然对旧值进行了某种缓存,然后比较旧的和新的。 这是这样做的方式,如果是这样,怎么样?或者是否有另一种可能更简单的方法而不需要缓存任何内容?

非常感谢任何帮助!

编辑: 基于@ NoobsArePeople2给出的示例,这是我当前的代码。 首先是DataGrid。 dataProvider是一个ArrayList,用于保存myModel类的对象。

<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属性相反),但是,当为多个网格列使用此项呈示器时,它对每个网格列使用相同的值。那是什么意思?

编辑:对不起,这只有在我直接解决模型的属性时才有效,比如data.property,我不能这样做。我需要为所有列提供一般项目渲染器。

2 个答案:

答案 0 :(得分:1)

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

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

override public function set data(value:Object):void
{
    if (value == data)
        return;
    myModelInstance = MyModelClass(value);
}

[Bindable]
private var myModelInstance:MyModelClass;

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

答案 1 :(得分:1)

可行的方法是自定义项呈示器。 item renderer将带有data属性(其中data是来自数据提供者的单个值),当数据提供程序在DataGrid上更改时,将为您设置该属性。你想要

  1. 添加previousData类型的新私有变量Object
  2. 覆盖项呈示器中data的setter。
  3. data的setter看起来像这样:

    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的属性并且不想使用硬代码值,这应该可行(注意:我实际上没有测试过这段代码,但它应该可以正常工作)。< / p>

    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
    }