Spark ItemRenderer“速记”导致奇怪的行为

时间:2013-04-17 17:45:50

标签: flex flex4 behavior itemrenderer

我有一个简单的ItemRenderer,当我在Spark产品列表中使用它时会导致奇怪的行为。它的定义如下:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  xmlns:mx="library://ns.adobe.com/flex/mx"
  creationComplete="setProduct()">

  <fx:Script>
    <![CDATA[

      [Bindable]
      private var p:MyProduct;

      private function setProduct():void
      {
        p = data as MyProduct;
      }

    ]]>
  </fx:Script>

  <s:Label text="{p.name}" paddingTop="6" paddingBottom="4"
    color="{p.active ? Constants.BLACK : Constants.DISABLED_COLOR}"
    fontStyle="{p.active ? 'normal' : FontStyle.ITALIC}"/>

</s:ItemRenderer>

它与List的默认ItemRenderer基本相同。我决定使用变量p,这样我就不必在Label绑定中反复编写(data as MyProduct)(这在更大,更复杂的ItemRenderers中特别麻烦)。

它导致的行为似乎“反转”显示的项目,但项目的实际顺序保持不变。当产品使用新值更新时会发生这种情况。例如,我将有一个产品列表A B C D。如果我更新其中任何一个的属性,列表会将订单更改为 show D C B A。但是如果我在这个反向列表中单击产品D,它仍然会“加载”产品A. This post describes a similar problem,但是没有包含代码,所以我不确定它是否完全相同。

我将此问题跟踪到使用变量p。如果我只在Label绑定中使用(data as MyProduct),它可以正常工作。如果我从上面的链接中获取示例并在setProduct()事件上运行dataChange方法,则该bug将消失并按预期工作。但是,我不相信这不仅仅是巧合。

有没有其他人经历过这样的事情?问题与使用creationComplete事件直接相关吗?我在想,也许creationComplete只会发射一次然后把一切都扔掉了。不知道这与列表中的任何内容有什么关系,反过来显示的产品。

2 个答案:

答案 0 :(得分:3)

这可能是因为物品渲染器被回收。我会覆盖数据设置器而不是使用creationComplete,这样你就可以确保捕获数据更改。

override public function set data(value : Object) : void {
    super.data = value;
    p = value as MyProduct;
}

答案 1 :(得分:1)

有一些事情。首先,如果你有一个你想要设置的值对象,那么我通常会在我的设置数据代码中进行。

override public function set data( value:OBject ):void
{
  super.data = value;
  p = value as MyProduct;
}

但与我认为的问题相比,这是相对较小的豆类。括号表示属性绑定到该对象/对象链。所以我们不得不问,这个陈述中的对象是什么?

"{p.active ? 'normal' : FontStyle.ITALIC}"

我并不是说它不应该起作用,但我们想尽可能多地吸烟。所以如果我是你,我的代码看起来就像这样。

[Bindable] public var fonstStyle:String;
[Bindable] public var color:int;
[Bindable] public var name:String;
private var _p:MyProduct;

override public function set data( value:OBject ):void
{
  super.data = value;
  _p = value as MyProduct;
  fonstStyle = _p.active ? 'normal' : FontStyle.ITALIC;
  color = _p.active ? Constants.BLACK : Constants.DISABLED_COLOR;
  name = _p.name;
}

我也会摆脱'creationComplete'事件监听器。使用ItemRenderers时,任何基于数据的属性设置都应通过“设置数据”功能完成。

现在我看一下你的代码,你的渲染器可能是在通过'creationComplete'创建后设置这些变量,然后它们没有被更新。