2011-08-25 2 views
1

현재 ArrayCollection 객체의 양방향 바인딩을 구현하려고합니다. 그러나 COLLECTION_CHANGE 이벤트가 발생하지 않습니다.플렉스 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 */ 
     } 
    } 
} 

은 내가 부스 변수 바인딩이 방향을 달성하기 위해 노력하고있어.

public var booths:ArrayCollection = new ArrayCollection(); 

그런데 : 나는 문제는 당신이이 컬렉션의 collectionChange 이벤트를 구독하는 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의 부스 속성이 새 값을 포함하기 전에 항목이 ArrayCollection에 추가 될 가능성이 있습니다. 따라서 컬렉션 변경 이벤트는 FloorplanGrid 내에서 결코 발생하지 않습니다.

또한이 FloorplanGrid의 생성자 내부의 수집 변경 이벤트에 대한 이벤트 리스너를 설정하는 '() 새로운 ArrayCollection에'당신이에서 이벤트를 수신하는 등으로

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

객체입니다 내부에 생성 구성 요소. 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

의 부스 변수에 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을 듣고 있다는 것을 알고 있습니다.

게터/세터 쌍을 사용하여 수동으로 수집 변화를 처리하는 경우에 당신은 아마이 바인딩을 할 필요가 없습니다

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를 추가하는 체크가 없습니다.

관련 문제