2011-08-25 79 views
1

我正在尝试实现ArrayCollection对象的2路绑定。但是,COLLECTION_CHANGE事件不会触发。Flex 4 COLLECTION_CHANGE事件没有触发

App.mxml

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       xmlns:components="components.*" 
       creationComplete="handleCreationComplete(event)"> 
    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 

      [Bindable] 
      public var booths:ArrayCollection;    

      public function handleCreationComplete(event:Event):void 
      { 
       // ADD SOME BOOTHS 
       booths = new ArrayCollection(); 
       booths.addItem("item1"); 
       booths.addItem("item2"); 
      } 

     ]]> 
    </fx:Script> 

    <components:FloorplanGrid id="grid" width="400" height="300" booths="{booths}" /> 
</s:Application> 

FloorplanGrid.as

package components 
{  
    import mx.collections.ArrayCollection; 
    import mx.events.CollectionEvent; 

    import spark.components.Group; 

    [Event(name="collectionChanged", type="events.CollectionEvent")] 

    public class FloorplanGrid extends Group 
    { 
     [Bindable] 
     public var booths:ArrayCollection = new ArrayCollection(); 

     public function FloorplanGrid() 
     { 
      booths.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothsChange); 
      super(); 
     } 

     private function handleBoothsChange(event:CollectionEvent):void 
     { 
      trace("HANDLE BOOTHS CHANGE"); 
      /* draw booths */ 
     } 
    } 
} 

我试图实现2路与摊位变量绑定。

public var booths:ArrayCollection = new ArrayCollection(); 

但后来:然而,当我加在App.mxml

回答

2

我不知道从哪里开始...

绑定在Flex事件系统上工作;所以当绑定被解开时,它不是即时/同步的。看看这些代码段:

 public function handleCreationComplete(event:Event):void 
     { 
      booths = new ArrayCollection(); 
      booths.addItem("item1"); 
      booths.addItem("item2"); 
     } 

<components:FloorplanGrid id="grid" width="400" height="300" booths="{booths}" /> 

因此,您所创建的摊位的ArrayCollection,并添加两个项目给它。这是同步代码,所以这三个项目都是正确的。展位ArrayCollection绑定到FloorplanGrid上的展位属性。此更新将异步发生;所以会有延迟。

因此,在FloorplanGrid的booths属性包含新值之前,项目很可能会添加到ArrayCollection中。因此,收集更改事件永远不会从FloorplanGrid中发出。

此外,要设置的事件侦听器的collect更改事件FloorplanGrid的构造函数中:内创建

public function FloorplanGrid() 
    { 
     booths.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothsChange); 
     super(); 
    } 

因此,你正在听有关事件“新ArrayCollection的()”对象零件。当您更改booths属性时,您尚未向新值添加事件侦听器;因此你没有事件监听器在使用。

您可能想要将您的booths属性更改为get/set属性。就像这样:

 private var _booths:ArrayCollection; 
     [Bindable] 
     public function get booths():ArrayCollection{ 
      return _booths; 
     } 
     public function set booths(value:ArrayCollection):void{ 
      if(_booths){ 
      _booths.removeEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothsChange); 
      } 
      _booths = value; 
      if(_booths){ 
      _booths.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothsChange); 
      } 
     } 

删除事件监听器并重新添加这将有助于防止内存泄漏在应用程序中。因为您的应用中不会有错误的监听器,所以无法收集旧值。

0

问题是你已经在collectionChange情况下,本集的订阅在摊位可变2个新项目COLLECTION_CHANGE事件从未火灾:

<components:FloorplanGrid id="grid" width="400" height="300" booths="{booths}" /> 

您已通过其他收集哪些事件未订阅。

您可以更改代码,如下所示:

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       xmlns:components="components.*" 
       creationComplete="handleCreationComplete(event)"> 
    <fx:Script> 
     <![CDATA[ 
      import mx.collections.ArrayCollection; 

      public function handleCreationComplete(event:Event):void 
      { 
       // ADD SOME BOOTHS 
       grid.booths.addItem("item1"); 
       grid.booths.addItem("item2"); 
      } 

     ]]> 
    </fx:Script> 

    <components:FloorplanGrid id="grid" width="400" height="300" /> 
</s:Application> 

或者创建拥有订阅/退订逻辑上FloorplanGrid的侧吸。

3

我不认为问题在于事件没有解雇。相反,我认为发生的事情是您正在监听您在变量声明中设置的原始ArrayCollection,而不是由应用程序中的绑定传入的原始ArrayCollection。

使用的getter/setter对:

protectect var _booths:ArrayCollection; 

[Bindable] 
public function get booths():ArrayCollection { 
    return _booths; 
} 

public function set booths(value:ArrayCollection):void { 
    if (value != _booths) { 
     if (_booths != null) { 
      _booths.removeEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothChange); 
     } 
     _booths=value; 
     if (_booths != null) { 
      _booths.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleBoothChange); 
     } 
     handleBoothChange(null); 
    } 
} 

请注意,你可能并不需要,使这个绑定,如果你手工处理收集的变化。

如果您使用的是FB 4.5,您可能需要考虑将其设置为模板 - 我使用这种类型的逻辑足以使我拥有自己的模板。 make getter/setter对是可以的,但它没有将侦听器从旧实例中移除并添加新的onw的检查。