使用项目渲染器时延迟打开组合框
我正在尝试找出一种方法来提高其中包含项目渲染的组合框的性能。 当我使用没有自定义项目渲染器的组合框时,下拉菜单快速打开,组合框非常敏感。 当我添加一个简单的项目渲染器时,它现在需要一秒钟才能打开组合框。 就像创建所有的孩子然后缓存它们一样。 之后,组合框将打开,直到您选择一个项目。 然后再打开组合框也需要一段时间。
以下是一个演示此问题的示例应用程序:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
height="100%" width="100%" xmlns:local="*"
>
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
public var dataProvider:ArrayCollection = new ArrayCollection(
[{label:"test1"},
{label:"test2"},
{label:"test3"}]);
]]></mx:Script>
<!-- combobox with item renderer, this has a delay when opening -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}">
<mx:itemRenderer>
<mx:Component>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="'item renderer' + {data.label}"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:ComboBox>
<!-- default combobox, this works fine -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}"/>
</mx:Application>
我在这里错过了什么? 这似乎不应该发生。
花了一些时间寻找解决方案后,我发现如果在<mx:Component>
只定义了一个“干净”子组件,则性能会更好。
所以下面的表现很好:
<mx:Component>
<mx:HBox /> ( "clean" )
</mx:Component>
而这一个表现不好(延迟):
<mx:Component>
<mx:HBox>
<mx:Label /> ( not "clean" )
</mx:HBox>
</mx:Component>
为了解决这个问题,我们可以使用代码创建子组件:
<mx:itemRenderer>
<mx:Component>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Label;
// Define the label instance
private var lbl:Label = new Label();
// Add the label as a child component
override protected function createChildren(): void {
super.createChildren();
addChild( lbl );
}
// Set the data
override public function set data( value:Object ): void {
super.data = value;
if ( value ) {
lbl.text = value.label;
}
}
]]>
</mx:Script>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
演示:https://github.com/jeantimex/flex-combobox-itemrenderer
希望有所帮助!
这可能是朝着正确方向迈出的一步; 但我无法保证解决方案。 我建议你首先重写你的itemRenderer不要使用绑定。 我已经通过教他们解决了许多付费客户的内存泄漏问题。 在itemRenderer中,绑定也被称为性能繁重的操作; 所以我会建议将它从操作中移除。
而不是在itemRenderer中使用绑定,我更愿意响应dataChange方法。
我也建议你从itemRenderer中移除HBox; 因为您应该能够按照原样使用该标签:
<mx:ComboBox width="200"
dataProvider="{dataProvider}">
<mx:itemRenderer>
<mx:Component>
<mx:Label dataChange="onDataChange(event)">
<mx:Script>
protected function onDataChange(event:Event):void{
this.text='item renderer' + data.label;
}
</mx:Script>
</mx:Label>
</mx:Component>
</mx:itemRenderer>
</mx:ComboBox>
我不确定这是否会解决任何性能问题。 在创建Flextras自动完成时,我必须通过Flex组合框来解决Flex组合框的很多问题。
内存告诉我,在Flex 3.4(和之前)每次关闭下拉菜单时, 它被摧毁 - 基本上没有被缓存在内存中。 这在Flex 3.5中发生了变化,而它们开始缓存并重新使用相同的下拉对象。 我想知道你觉得的性能问题是否与此有关。
编辑1:基于对这个帖子的投诉,没有解决潜在的问题; 我根据原始海报代码和我建议的更改将这个测试案例放在一起。 我提出的改变确实解决了原始海报的问题。 这是样本背后的来源:
[Bindable]
public var dataProvider:ArrayCollection = new ArrayCollection(
[{label:"test1"},
{label:"test2"},
{label:"test3"}]);
]]></mx:Script>
<!-- combobox with item renderer, this has a delay when opening -->
<mx:VBox>
<!-- ComboBox provided by original poster -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}">
<mx:itemRenderer>
<mx:Component>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Label text="'item renderer' + {data.label}"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:ComboBox>
<!-- ComboBox with rewritten itemRenderer; which does not exhibit the problem -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}">
<mx:itemRenderer>
<mx:Component>
<mx:Label dataChange="label1_dataChangeHandler(event)">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function label1_dataChangeHandler(event:FlexEvent):void
{
this.text = "item renderer" + data.label;
}
]]>
</mx:Script>
</mx:Label>
</mx:Component>
</mx:itemRenderer>
</mx:ComboBox>
<!-- default combobox, this works fine -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}"/>
</mx:VBox>
编辑2:devshorts说我的代码不起作用,如果我们创建组件作为独立的itemRenderer; 但我不明白为什么不。
以下是独立itemRenderer的代码,名称为com.flextras.listRenderers.CustomLabelRenderer:
<?xml version="1.0" encoding="utf-8"?>
<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" dataChange="label1_dataChangeHandler(event)">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function label1_dataChangeHandler(event:FlexEvent):void
{
this.text = "item renderer" + data.label;
}
]]>
</mx:Script>
</mx:Label>
这里有一些代码添加到上面的邮件应用程序来测试它:
<!-- ComboBox, like above with the itemRenderer as a separate component -->
<mx:ComboBox width="200"
dataProvider="{dataProvider}" itemRenderer="com.flextras.listRenderers.CustomLabelRenderer" />
我在我提供的链接上更新了应用程序,以包含这个新的ComboBox实例; 它现在是名单上的第三位。
链接地址: http://www.djcxy.com/p/34583.html上一篇: Delay in opening combobox when using an item renderer
下一篇: Set selectedItem on a Flex Combobox when the Combobox is not displayed?