Flex3:自定义项目渲染器不侦听父级调度的事件

发布于 2024-07-17 09:18:49 字数 1884 浏览 7 评论 0原文

我有一个带有自定义 ItemRenderer 的列表。 ItemRenderer 包含一个复选框和一个标签。 带有列表的组件有一个“全选”复选框。 当选中“全选”复选框时,它会调度每个项目应侦听的事件,以便选择自己的复选框。 事件侦听器是在每个项目的creationComplete 上添加的,并且当选中“全选”复选框时会正确分派事件,但自定义ItemRenderer 中的侦听器不会侦听。

如何使 ItemRenderer 侦听在其父级中分派的事件?

我将添加一些代码示例来澄清:

------- container ----------
<mx:VBox>
   <mx:Script>
      <![CDATA[
         public var user1 = new User(1, "Jack");
         public var user2 = new User(2, "John");
         public var user3 = new User(3, "Mary");

         [Bindable]
         public var users:ArrayCollection = new ArrayCollection([user1], [user2], [user3]);

         public static const SELECT_ALL_USERS:String = "selectAllUsers";

         private function selectAllChangeHandler():void
         {
            if (selectAll.selected)
               dispatchEvent(new Event(SELECT_ALL_USERS,true));
         }
      ]]>
   </mx:Script>
   <mx:CheckBox id="selectAll" change="{selectAllChangeHandler()}" />
   <mx:List dataProvider="{users}" itemRenderer="myRenderer" />
</mx:VBox>


------- renderer ----------
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox creationComplete="{init()}">
   <mx:Script>
      <![CDATA[
         private function init():void
         {
            addEventListener (Container.SELECT_ALL, selectAllHandler, false, 0, true);
         }

         private function selectAllHandler():void
         {
            checkbox.selected=true;
         }

         private function selected(id:int):Boolean
         {
             return id==1 || id==3;
         }
      ]]>
   </mx:Script>

   <mx:CheckBox id="checkbox" selected="{selected(data.id)}" />
   <mx:Label text="{data.name}" />
</mx:HBox>

请注意,用户 ArrayCollection 或其包含的用户对象无法更改,因为我稍后需要这些值。 因此,当单击“selectAll”时,还应选中列表中的每个复选框。

I have a List with a custom ItemRenderer. The ItemRenderer contains a Checkbox and a Label.
The component with the List has a 'select all' checkbox.
When the 'select all' checkbox is checked, it dispatches an event that each item should listen to in order to select its own checkbox.
The eventlistener is added on creationComplete of each item, and the event is dispatched correctly when the 'select all' checkbox is selected, but the listener in the custom ItemRenderer does not listen.

How do I make the ItemRenderer listen to an event that is dispatched in its parent??

I'll add some code examples to clarify:

------- container ----------
<mx:VBox>
   <mx:Script>
      <![CDATA[
         public var user1 = new User(1, "Jack");
         public var user2 = new User(2, "John");
         public var user3 = new User(3, "Mary");

         [Bindable]
         public var users:ArrayCollection = new ArrayCollection([user1], [user2], [user3]);

         public static const SELECT_ALL_USERS:String = "selectAllUsers";

         private function selectAllChangeHandler():void
         {
            if (selectAll.selected)
               dispatchEvent(new Event(SELECT_ALL_USERS,true));
         }
      ]]>
   </mx:Script>
   <mx:CheckBox id="selectAll" change="{selectAllChangeHandler()}" />
   <mx:List dataProvider="{users}" itemRenderer="myRenderer" />
</mx:VBox>


------- renderer ----------
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox creationComplete="{init()}">
   <mx:Script>
      <![CDATA[
         private function init():void
         {
            addEventListener (Container.SELECT_ALL, selectAllHandler, false, 0, true);
         }

         private function selectAllHandler():void
         {
            checkbox.selected=true;
         }

         private function selected(id:int):Boolean
         {
             return id==1 || id==3;
         }
      ]]>
   </mx:Script>

   <mx:CheckBox id="checkbox" selected="{selected(data.id)}" />
   <mx:Label text="{data.name}" />
</mx:HBox>

Please note that the users ArrayCollection or its containing user objects cannot be changed because I need the values later on.
So when 'selectAll' is clicked, each checkbox in the list should also be checked.

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

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

发布评论

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

评论(4

混吃等死 2024-07-24 09:18:49

您的自定义 ItemRenderers 不应向其父级注册事件侦听器,而应使用“全选”复选框注册事件侦听器,即如果

theCheckbox.addEventListener(YourEvent.YOUR_EVENT, itemRendererSelectAllHandler);

失败,您可以发布添加事件侦听器并从复选框分派事件的代码吗?

编辑:

这是您的错误:在渲染器的 init() 中,您需要添加一个事件侦听器,而不是向渲染器添加事件侦听器,而是向调度事件的容器添加事件侦听器。 所以将其设为

container.addEventListener(Container.SELECT_ALL_USERS, selectAllHandler, false, 0, true);

Your custom ItemRenderers should not register an event listener with their parent, but with your "select all" checkbox, i.e.

theCheckbox.addEventListener(YourEvent.YOUR_EVENT, itemRendererSelectAllHandler);

Failing that, can you post your code which adds the event listener and which dispatches the event form the checkbox?

edit:

Here's your bug: In renderer's init(), you need to add an event listener not to the renderer, but to the container which dispatches the event. So make that a

container.addEventListener(Container.SELECT_ALL_USERS, selectAllHandler, false, 0, true);
§对你不离不弃 2024-07-24 09:18:49

在 Flex 中进行全选并不复杂,但我会告诉你我们是如何做到的,而且效果很好。

我们创建了一个名为“ExList”的列表派生控件,它具有一个属性“selectAllCB”,我们将其绑定到现有复选框,该复选框将适用于选择所有逻辑。 请注意,当我们设置 selectAllCB 属性时,我们使 ExList 监听复选框的事件。

选中复选框后,我们手动将 selectedItems 数组设置为 dataProvider 数组,并选择所有项目。

使用 itemRenderer 无法正常工作,因为当您一次又一次地对列表进行编程时,您必须编写大量代码。

I am attaching some sample code here below..

    public class ExList extends List 
    {
        public function ExTileList()
        {
            super();
            this.allowMultipleSelection = true;
        }

        private var _selectAllCB:CheckBox = null;
        [Bindable]
        public function get selectAllCB():CheckBox
        {
            return _selectAllCB;
        }
        public function set selectAllCB(v:CheckBox):void
        {
            if(v==null)
                return;
            _selectAllCB = v;
            v.addEventListener(ListEvent.ITEM_CLICK, handleAllChange,false, 0 , true);
            v.addEventListener("change", handleAllChange,false, 0 , true);
        }

        private function handleAllChange(e:Event):void
        {
            if(_selectAllCB.selected)
            {
                this.selectedItems = this.dataProvider.toArray();
            }
            else
            {
                this.selectedItems = new Array();
            }
        }
}

您可以将它用作...

<CheckBox id="sAll"/>
<ExList selectAllCB="{sAll}"/>

// Please note its in curly braces

Doing select all in flex is little complex but I will tell you the way we did it and it works great.

We created a List derived control called "ExList" which has a property "selectAllCB" which we bind it to existing check box which will work for select all logic. Please note, when we set selectAllCB property, we make ExList to listen to checkbox's events.

When checkbox is checked, we manually set selectedItems array to array of dataProvider and all items are selected.

Playing with itemRenderer doesnt work correctly because when you program your list again and again everytime you have to write so much of code.

I am attaching some sample code here below..

    public class ExList extends List 
    {
        public function ExTileList()
        {
            super();
            this.allowMultipleSelection = true;
        }

        private var _selectAllCB:CheckBox = null;
        [Bindable]
        public function get selectAllCB():CheckBox
        {
            return _selectAllCB;
        }
        public function set selectAllCB(v:CheckBox):void
        {
            if(v==null)
                return;
            _selectAllCB = v;
            v.addEventListener(ListEvent.ITEM_CLICK, handleAllChange,false, 0 , true);
            v.addEventListener("change", handleAllChange,false, 0 , true);
        }

        private function handleAllChange(e:Event):void
        {
            if(_selectAllCB.selected)
            {
                this.selectedItems = this.dataProvider.toArray();
            }
            else
            {
                this.selectedItems = new Array();
            }
        }
}

And you can use it as...

<CheckBox id="sAll"/>
<ExList selectAllCB="{sAll}"/>

// Please note its in curly braces
傲影 2024-07-24 09:18:49

这就是我实现解决方案的方法:

    <?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" height="150" verticalGap="0">
    <mx:Script>
 <![CDATA[
         import mx.events.ListEvent;
  import mx.controls.CheckBox;
  import mx.collections.ArrayCollection;

  public var listData:ArrayCollection;

  private function selectAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   {
    CheckBox(listChkBox.itemToItemRenderer(item)).selected = true;
          }   
  }

  private function resetAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   { 
                         CheckBox(listChkBox.itemToItemRenderer(item)).selected = false;
   } 
  }


  ]]>
 </mx:Script>
 <mx:List width="100%" height="100%" id="listChkBox" labelField="name" allowMultipleSelection="true"
   dataProvider="{listData}"  selectionColor="#FFFFFF" >
  <mx:itemRenderer>
   <mx:Component>
    <mx:CheckBox >
    </mx:CheckBox>
   </mx:Component>
  </mx:itemRenderer>
 </mx:List>
 <mx:HBox width="100%"  backgroundColor="#E2DEDE" paddingBottom="2" paddingLeft="2" paddingTop="2" paddingRight="2" borderStyle="solid">
  <mx:Button label="All"  id="btnAll" click="selectAll()" />
  <mx:Button label="None" click="resetAll()"/>
 </mx:HBox>
</mx:VBox>

This is how I achieved the solution:

    <?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" height="150" verticalGap="0">
    <mx:Script>
 <![CDATA[
         import mx.events.ListEvent;
  import mx.controls.CheckBox;
  import mx.collections.ArrayCollection;

  public var listData:ArrayCollection;

  private function selectAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   {
    CheckBox(listChkBox.itemToItemRenderer(item)).selected = true;
          }   
  }

  private function resetAll():void
  {
   listChkBox.selectedItems = listData.toArray();
   for each (var item:Object in listChkBox.selectedItems)
   { 
                         CheckBox(listChkBox.itemToItemRenderer(item)).selected = false;
   } 
  }


  ]]>
 </mx:Script>
 <mx:List width="100%" height="100%" id="listChkBox" labelField="name" allowMultipleSelection="true"
   dataProvider="{listData}"  selectionColor="#FFFFFF" >
  <mx:itemRenderer>
   <mx:Component>
    <mx:CheckBox >
    </mx:CheckBox>
   </mx:Component>
  </mx:itemRenderer>
 </mx:List>
 <mx:HBox width="100%"  backgroundColor="#E2DEDE" paddingBottom="2" paddingLeft="2" paddingTop="2" paddingRight="2" borderStyle="solid">
  <mx:Button label="All"  id="btnAll" click="selectAll()" />
  <mx:Button label="None" click="resetAll()"/>
 </mx:HBox>
</mx:VBox>
情深如许 2024-07-24 09:18:49

简单的解决方案是在所呈现的数据列表中使用类型化对象,然后利用数据绑定和绑定实用程序来捕获项目渲染器上基础数据属性的更改。 当对象中的某些属性发生更改以反映“全选/取消全选”状态时,覆盖项目渲染器中的“设置数据”功能以执行您需要的任何操作。

The simple solution is to use typed objects in the list of data you are presenting and then take advantage of databinding and the binding utils to capture changes to the underlying data property on the item renderer. Override the 'set data' function in the item renderer to do whatever you need when some property in the object gets changed to reflect the 'select all/de select all' state.

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