在 dataprovider 中缓存变量

发布于 2024-12-24 18:47:01 字数 2024 浏览 3 评论 0原文

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

在我的 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 属性相反),但是,当对多个网格列使用这个项目渲染器时,它对每个网格列使用相同的值。那是关于什么的?

编辑:抱歉,只有当我直接寻址模型的属性(例如 data.property)时,这才有效,但我不能这样做。我需要一个适用于所有列的通用项目渲染器。

I've got a model class with a bunch of Number variables that change frequently.
They all dispatch their custom events, thus are bindable.

In my UI, a couple of those class instances are bundled into an ArrayList that serves as the dataprovider for a Spark DataGrid.
The class variables change perfectly fine, so problem there.

What I'd like to do now is to change the color formatting of those numbers (the corresponding labels in the gridcoloums to be exact) depending on the data that comes in, so to say change in green when the new value is bigger, change to red when the new value is smaller than the old one.

How can I make this work? I though about some sort of caching of the old value and then compare the old and new one.
Is this the way to do this, if so, how? Or is there another, probably simpler way without the need to cache anything?

Any help would be much appreciated!

Edit:
Based on the example given by @NoobsArePeople2, this is my current code.
First the DataGrid. The dataProvider is an ArrayList that holds objects of myModel class.

<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>

Now the tableCell renderer;

<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>

This works fine so far (opposed to using the data property which throws an undefined error), however, when using this very item renderer for multiple grid columns, it uses the same values for each grid column. What's that about?

Edit: Sorry, this works only if I directly address the property of the Model, such like data.property, which I can't do. I need a general item renderer for all columns.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流年已逝 2024-12-31 18:47:01

正确的方法是自定义项目渲染器。 项目渲染器将附带一个 data 属性(其中 data 是来自数据提供程序的单个值)当您的数据提供者在 DataGrid 上发生更改时,将会为您进行设置。您需要

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

您的 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

}

或者,如果您需要访问 < 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
}

The way to go is a custom item renderer. An item renderer will come with a data property (where data is a single value from your data provider) that will get set for you when your data provider changes on the DataGrid. You'll want to

  1. Add a new private variable previousData of type Object, and
  2. Override the setter for data in your item renderer.

Your setter for data will look something like this:

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();
}

Then, in your item renderer, override the commitProperties() method like this:

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

}

Alternatively, if you need to access properties of data and don't want to hard code values this should work (note: I haven't actually tested this code, but it should work just fine).

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
}
流年已逝 2024-12-31 18:47:01

我认为您应该为数据网格创建自定义项目渲染器。您应该覆盖 data setter 并使用 BindingUtils 来处理字段更改。示例用法位于此处

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

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

[Bindable]
private var myModelInstance:MyModelClass;

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

I think you should create your custom item renderer for your data grid. There you should override data setter and use BindingUtils to handle field changes. The sample usage is here.

Or you can reassign your data in item renderer the following way:

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

[Bindable]
private var myModelInstance:MyModelClass;

And then bind to the fields of myModelInstance in MXML item renderer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文