2011-08-25 80 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的檢查。