2012-01-05 9 views
0

У меня есть модельный класс с множеством переменных Number, которые часто меняются. Все они отправляют свои пользовательские события, поэтому они могут быть привязаны.Переменные кэша в dataprovider

В моем пользовательском интерфейсе несколько экземпляров этого класса объединены в массив ArrayList, который служит в качестве датапараудера для Spark DataGrid. Переменные класса изменяются отлично, поэтому проблема там.

Теперь я хочу изменить цветное форматирование этих чисел (соответствующие метки в gridcoloums, если быть точным) в зависимости от данных, которые поступают, так сказать изменение зеленого цвета, когда новое значение больше, меняется на красный, когда новое значение меньше старого.

Как это сделать? Я хоть о каком-то кешировании старого значения, а затем сравниваю старый и новый. Это способ сделать это, если да, то как? Или есть другой, возможно более простой способ без необходимости кэшировать что-нибудь?

Любая помощь была бы высоко оценена!

Редактировать: На основании примера, данного @ 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.property, чего я не могу сделать. Мне нужен общий рендеринг элементов для всех столбцов.

ответ

1

Способ перехода - это средство визуализации элементов. Объект item renderer будет иметь свойство data (где data - это единственное значение вашего поставщика данных), которое будет установлено для вас при изменении вашего поставщика данных в DataGrid. Вы хотите, чтобы

  1. Добавить новую приватную переменную previousData типа Object и
  2. Override сеттер для 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 
} 
+0

Thanks @ NoobsArePeople2 Я понимаю, что вы здесь делаете, и в основном это именно то, что я считал нужным. Тем не менее, у меня есть небольшие проблемы с вашим решением (голые со мной здесь, я до сих пор не работал с itemrenderers). Во-первых, значение if (data ==) выдает ошибку «undefined». Во-вторых, объект value будет иметь тип myModel, даже если для поля данных на соответствующем GridColumn установлено значение myModel.change, которое представляет собой Number. Я добавил свой рендерер (на основе вашего кода) к первому вопросу выше. – AlBirdie

+0

Это потому, что в моем образце кода была ошибка. См. Часть, начинающуюся с 'BEGIN EDIT' – NoobsArePeople2

+0

Что-то действительно здесь. Несмотря на то, что в столбцах сетки данных я получаю правильные значения (в том числе обновления) БЕЗ средства рендеринга элементов, простая трассировка на значение, отлитое в Number в рендерере элементов всегда выводит NaN на каждое обновление, которое я действительно не понимаю как правильные цифры отображаются для столбцов в сетке данных без средства рендеринга элементов. – AlBirdie

1

Я думаю, вы должны создать свой собственный инструмент визуализации элементов для своей сетки данных. Там вы должны переопределить сеттер data и использовать BindingUtils для обработки изменений полей. Пример использования here.

Или вы можете передать данные в визуализации элемента следующим образом:

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

[Bindable] 
private var myModelInstance:MyModelClass; 

А затем связываются с полями myModelInstance в MXML визуализации элементов.