Событие Flex 4 COLLECTION_CHANGE не запускается - PullRequest
1 голос
/ 25 августа 2011

В настоящее время я пытаюсь добиться двухстороннего связывания объекта ArrayCollection.Однако событие 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 */
        }
    }
}

Я пытаюсь добиться двустороннего связывания спеременная Booths .Однако событие COLLECTION_CHANGE никогда не срабатывает, даже когда я добавляю 2 новых элемента в переменную Booths в App.mxml

Ответы [ 3 ]

2 голосов
/ 25 августа 2011

Не думаю, что проблема в том, что событие не запускается.Вместо этого я думаю, что происходит то, что вы слушаете оригинальную коллекцию ArrayCollection, которую вы установили в объявлении переменной, а не ту, которая передана привязкой в ​​приложении.

Используйте метод получения / установкиpair:

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.

1 голос
/ 25 августа 2011

Я не уверен, с чего начать ...

Связывание работает в системе событий 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. Это обновление будет происходить асинхронно; поэтому будет задержка.

Таким образом, вполне вероятно, что элементы будут добавлены в ArrayCollection до того, как свойство booths в FloorplanGrid будет содержать новое значение. Таким образом, событие изменения коллекции никогда не запускается из FloorplanGrid.

Кроме того, вы устанавливаете прослушиватель событий для события сбора изменений в конструкторе FloorplanGrid:

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

Таким образом, вы прослушиваете событие в объекте 'new 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 голосов
/ 25 августа 2011

Проблема в том, что вы подписались на collectionChange событие этой коллекции:

public var booths:ArrayCollection = new ArrayCollection();

Но тогда:

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

вы передали другую коллекцию, событие которой не было 't подписано.

Вы можете изменить код следующим образом:

<?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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...