【问题标题】:Event priority for different components in FlexFlex 中不同组件的事件优先级
【发布时间】:2012-06-20 09:56:57
【问题描述】:

我有以下代码,其中包含与每个元素关联的事件。当我单击单选按钮时,属于tableonItemClick 事件在onSelect 事件之后执行。我认为这是因为table 是父母,rb2 是孩子。

private function onItemClick(e:ListEvent):void {
    selectedRow = parseInt(e.itemRenderer.data.Id)-1;
    trace("selectedRow: "+selectedRow);
}

public function selectPoint(event:MouseEvent):void{
    trace("selectPoint");
}

<mx:DataGrid id="table" dataProvider="{listCol}"
         itemClick="onItemClick(event)">
<mx:columns>
    <mx:DataGridColumn id="posibilidades" rendererIsEditor="true" 
                       editorDataField="selected" headerText="Posibilidades" width="100" textAlign="center"
                       draggable="false" editable="false" resizable="false" sortable="false">
        <mx:itemRenderer>
            <mx:Component>
                <mx:RadioButton name="rb2" label="Punto 2" fontSize="13" enabled="false" 
                                groupName="_rb" value="1" textAlign="center" 
                                preinitialize="event.target.styleName='rbstyle'"
                                click="outerDocument.selectPoint(event)"
                                creationComplete="outerDocument.rbCreated(event)"/>
            </mx:Component>
        </mx:itemRenderer>
    </mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>

我需要以相反的顺序执行这两个事件:onItemClick,然后是onSelect

如何在onSelect 之前执行onItemClick?我读过一些关于与addEventListener 相关的优先级的内容,但它不起作用,因为事件是针对不同组件的。

编辑: 我将尝试解释我的问题以及为什么我在 Flex 中做这些奇怪的事情。

我有一个 Datagrid 组件,它通过一个名为“添加度量”的按钮动态更新。这个 Datagrid 有 4 列;添加到此 Datagrid 的每个度量都有两个单选按钮作为最后一个单元格(在第 4 列)。

|-----------------------------------------------------------------------------|
|            |             |             |                                    |
|  #1 cell   |   #2 cell   |   #3 cell   | (o) Radiobutton1  (o) Radiobutton2 |
|            |             |             |                                    |
|-----------------------------------------------------------------------------|

问题是:当我删除一行时,数据会从显示中删除并且工作正常。但是当我添加一个新单选按钮时,Flex 会重用单选按钮,我无法知道新单选按钮在哪一行(如果 Flex 重用它们并且我删除 3 行并添加一个新单选按钮,那么单选按钮 -按钮属于这个新行,可以属于删除的最后一行,也可以属于另一个;无法保证)。

所以,我想:“好吧,Fran,也许你可以在Datagrid中为itemClick添加一个事件监听器,当用户点击单选按钮时,你可以知道最近点击的单选按钮在哪一行(因为itemClick 处理程序)”。但是 Flex 并没有按照我预期的顺序执行处理程序,所以我现在真的卡住了。

我正在尝试 onRollOver 事件而不是 onItemClick 并且效果很好,但并非总是如此。

【问题讨论】:

  • 依赖事件触发顺序被认为是不好的做法,因为它违背了异步编程的本质。我认为你应该考虑一种不同的方法。
  • 谢谢,我想像你写的那样,但这应该是同步模式:(
  • 您可以使用callLater(outerDocument.selectPoint, [event])selectPoint 方法的执行推迟到下一个渲染周期,但我强烈建议您不要这样做。或许您更应该解释您正在尝试完成的行为,以便我们可以更好地帮助架构。
  • 好的,我要编辑我自己的帖子 =)
  • 好的,我现在明白了。阅读此答案:stackoverflow.com/questions/8925474/…。和你的情况有点不同,但是原理是一样的。

标签: events apache-flex


【解决方案1】:

您可以在两个事件处理程序中将这两个事件添加为一个全局数组(或使用单个事件处理程序)。每次检查数组大小是否长度为2,并包含ListEvent和MouseEvent,并使用if(event is ListEvent)处理事件对象,否则......

然后清除数组,为下一个要触发的事件做好准备。

【讨论】:

    【解决方案2】:

    您为什么不在 DataGrid 上保留一个侦听器(onItemClick(e:Event)) 并使用“currentTarget”和“target”来识别导致点击的人并按照您想要的方式执行您的序列。在这种情况下,target.id 将是“rb2”,而 currentTarget.id 将是“tabe”。

        protected function onItemClick(event:Event):void
        {
            //handle your table click here.
            selectedRow = parseInt(event.itemRenderer.data.Id)-1;
            if(event.target.id == 'rb2')
            {
                //do something
            }
        }
    

    希望对你有帮助。

    【讨论】:

    • 谢谢,但问题是我需要先知道行,然后执行单选按钮点击处理程序。
    • 编辑了我的代码以包含您问题中的一些代码。您将首先获得该行,然后将移动为单选按钮执行您的逻辑。
    【解决方案3】:

    如果问题是在 flex 回收 itemrender 时识别当前行,我们可以在 itemRenderer 中使用一个事件监听器。创建一个新的 CustomItemRender 类,它扩展了 uiComponent 并实现了 IDropInListItemRenderer 和 IListItemRenderer。使用 listdata 和 data 属性访问行信息和数据信息。

    例如CustomRenderer代码如下:

    包装 { 导入 flash.events.MouseEvent;

    import mx.controls.DataGrid;
    import mx.controls.RadioButton;
    import mx.controls.listClasses.BaseListData;
    import mx.controls.listClasses.IDropInListItemRenderer;
    import mx.controls.listClasses.IListItemRenderer;
    import mx.core.UIComponent;
    
    public class CustomItemRender extends UIComponent implements IDropInListItemRenderer,IListItemRenderer
    {
        public function CustomItemRender()
        {
            super();
        }
    
    
        private var _data:Object
        public function get data():Object
        {
            return _data;
        }
    
        public function set data(value:Object):void
        {
            _data = value;
        }
    
        private var _listData:BaseListData
        public function get listData():BaseListData
        {
            return _listData;
        }
    
        public function set listData(value:BaseListData):void
        {
            _listData = value;
        }
    
        private var radioButton:RadioButton;
        override protected function createChildren():void {
            super.createChildren();
            if(!radioButton){
                radioButton = new RadioButton();
                radioButton.addEventListener(MouseEvent.CLICK, handleRadioButtonClick, false, 0, true);
                this.addChild(radioButton);
            }           
        }
    
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            radioButton.move(10, unscaledHeight*0.5);
        }
    
        private function handleRadioButtonClick(event:MouseEvent):void{
            trace("row data: "+data);
            trace("currently visible row Info: "+listData.rowIndex+" "+listData.columnIndex);
            trace("dataprovider "+DataGrid(listData.owner).dataProvider.toString())
        }
    }
    

    }

    这个例子不能解决你的问题。我希望这会对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多