Вручную отправьте событие изменения коллекции - PullRequest
1 голос
/ 14 марта 2011

У меня есть стандартный выпадающий список, который отправляет событие сбора после завершения инициализации поставщика данных:

my_cb.addEventListener (CollectionEvent.COLLECTION_CHANGE, getMyStuff);

Тогда у меня есть пользовательский компонент, который также имеет dataProvider. Как заставить его отправлять событие изменения коллекции, когда поставщик данных завершает загрузку?

Из того, что я прочитал, я не могу этого сделать. Будет ли работать диспетчеризация имущества?

Спасибо за любые полезные советы!

UPDATE:

У меня есть пользовательский компонент, который я называю 'SortingComboBox', но это вообще не ComboBox; он расширяет Button, и я устанавливаю свойство dataProvider в мою коллекцию массивов model.product (которая является коллекцией массивов).

А вот как я использую dataProvider в этом компоненте:

code

[Bindable] закрытый var _dataProvider: Object;

    public function get dataProvider() : Object
    {
        return _dataProvider;
    }

    public function set dataProvider(value : Object) : void
    {
        _dataProvider = value;

    }

code

В методе createChildren () этого компонента я использую это:

BindingUtils.bindProperty (dropDown, «dataProvider», this, «dataProvider»);

dropDown - это пользовательский VBox, который я использую для отображения меток.

Ответы [ 5 ]

1 голос
/ 15 марта 2011

Хорошо, этот код здесь

[Bindable]
private var _dataProvider : Object;

public function get dataProvider() : Object
{
   return _dataProvider;
}
public function set dataProvider(value : Object) : void
{
  _dataProvider = value;
}

ничем не отличается от

[Bindable]
public var _dataProvider : Object;

Поскольку объекты передаются по ссылке, вы все равно их не защищаете, а установщик и получатель бессмысленны.
С другой стороны, вы сделали исходный объект _dataProvider Bindable таким образом, чтобы при изменении данных он отправлял коллекцию CollectionEvent.COLLECTION_CHANGE.

1 голос
/ 15 марта 2011

это пользовательский компонент, чтобы дать вам лучшую идею.

code пакет com.fidelity.primeservices.act.components.sortingcombobox { import com.fidelity.primeservices.act.events.component.ResetSortEvent; import com.fidelity.primeservices.act.events.component.SortEvent;

import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;

import mx.binding.utils.BindingUtils;
import mx.controls.Button;
import mx.core.UIComponent;
import mx.effects.Tween;
import mx.events.FlexMouseEvent;
import mx.managers.PopUpManager;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;

public class SortingComboBox extends Button
{
    private const MAX_LABEL_LENGTH : int = 400; 
    private const ELIPSES : String = "...";

    [Bindable]
    private var _dataProvider : Object;
    private var dropDown : SortingDropDown;
    private var inTween : Boolean;
    private var showingDropdown : Boolean;
    private var openCloseTween : Tween;

    public var noSelectionLabel : String = "No Filter";
    public var noSelectionData : String = "ALL"; 

    public function get dataProvider() : Object
    {
        return _dataProvider;
    }

    public function set dataProvider(value : Object) : void
    {
        _dataProvider = value;
    }

    private function collectionEvent(e : Event):void
    {
        trace(new Date(), e);   
    }


    public function SortingComboBox()
    {
        super();
        this.buttonMode = true;
        this.useHandCursor = true;

        inTween = false;
        showingDropdown = false;

        addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
    }   

    override protected function createChildren() : void
    {
        super.createChildren();

        dropDown = new SortingDropDown();
        dropDown.width = 240;
        dropDown.maxHeight = 300;
        dropDown.visible = false;
        BindingUtils.bindProperty(dropDown, "dataProvider", this, "dataProvider");
        dropDown.styleName = "sortingDropDown";

        dropDown.addEventListener(SortEvent.CLOSE_SORT, closeDropDown);
        dropDown.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, dropdownCheckForClose);
        dropDown.addEventListener(FlexMouseEvent.MOUSE_WHEEL_OUTSIDE, dropdownCheckForClose);

        dropDown.addEventListener(SortEvent.UPDATE_SORT, onSortUpdate); //this event bubbles
        dropDown.addEventListener(ResetSortEvent.RESET_SORT_EVENT, onSortUpdate);

        PopUpManager.addPopUp(dropDown, this);

        this.addEventListener(MouseEvent.CLICK, toggleDropDown);

        // weak reference to stage
        systemManager.addEventListener(Event.RESIZE, stageResizeHandler, false, 0, true);
    }


    private function stageResizeHandler(evt : Event) : void
    {
        showingDropdown = false;
        dropDown.visible = showingDropdown;
    }

    private function toggleDropDown(evt : MouseEvent) : void
    {
        if(!dropDown.visible)
        {
            openDropDown(evt);
        }
        else
        {
            closeDropDown(evt);
        }               
    }

    private function openDropDown(evt : MouseEvent) : void
    {
        if (dropDown.parent == null)  // was popped up then closed
        {
            PopUpManager.addPopUp(dropDown, this);
        }
        else
        {
            PopUpManager.bringToFront(dropDown);
        }

        showingDropdown = true;
        dropDown.visible = showingDropdown;
        dropDown.enabled = false;

        var point:Point = new Point(0, unscaledHeight);
        point = localToGlobal(point);
        point = dropDown.parent.globalToLocal(point);

        //if the dropdown is larger than the button and its
        //width would push it offscreen, align it to the left.
        if (dropDown.width > unscaledWidth && point.x + dropDown.width > screen.width)
        {
            point.x -= dropDown.width - unscaledWidth;
        }

        dropDown.move(point.x, point.y);            

        //run opening tween
        inTween = true;

        // Block all layout, responses from web service, and other background
        // processing until the tween finishes executing.
        UIComponent.suspendBackgroundProcessing();

        dropDown.scrollRect = new Rectangle(0, dropDown.height, dropDown.width, dropDown.height);
        openCloseTween = new Tween(this, dropDown.height, 0, 250);
    }

    private function closeDropDown(evt : Event) : void
    {
        //dropDown.visible = false;             
        showingDropdown = false;

        //run closing tween
        inTween = true;

        // Block all layout, responses from web service, and other background
        // processing until the tween finishes executing.
        UIComponent.suspendBackgroundProcessing();

        openCloseTween = new Tween(this, 0, dropDown.height, 250);
    }

    private function dropdownCheckForClose(event : MouseEvent) : void
    {
        if (event.target != dropDown)
            // the dropdown's items can dispatch a mouseDownOutside
            // event which then bubbles up to us
            return;

        if (!hitTestPoint(event.stageX, event.stageY, true))
        {
            closeDropDown(event);
        }
    }

    public function refresh():void
    {
        onSortUpdate(null);   
    }

    private function onSortUpdate(evt1 : Event) : void
    {
        //update the label          
        var dpLength : int = this.dataProvider.length;  

        var nextLabel : String = "";
        var nextData : String = "";

        for (var i : int = 0; i < dpLength; i++)
        {
            if (this.dataProvider[i].selected == true)
            {
                nextLabel += this.dataProvider[i].label + ", ";                     
                if (this.dataProvider[i].data != null)
                {
                    nextData += this.dataProvider[i].data + ", ";
                }
            }
        }

        if (nextLabel.length > 0)
        {
            // remove extra comma at end
            nextLabel = nextLabel.substr(0, nextLabel.length - 2);
        }

        if (nextData.length > 0)
        {
            nextData = nextData.substr(0, nextData.length - 2);
        }

        if (nextLabel.length > MAX_LABEL_LENGTH)
        {
            // limit label to MAX_LABEL_LENGTH  + ... REASON: tooltips with lots of characters take a long time to render
            nextLabel = nextLabel.substr(0, MAX_LABEL_LENGTH) + ELIPSES;                    
        }

        if (nextLabel.length == 0)
        {
            nextLabel = noSelectionLabel;
            //nextLabel = "No Filter";
        }

        if (nextData.length == 0)
        {
            nextData = noSelectionData;
            //nextData = "ALL";
        }

        label = nextLabel;
        data = nextData;
        toolTip = label;

        if (evt1 is SortEvent)
        {
            trace("sort event");
            var temp:Object = this.dataProvider;
            this.dataProvider = null;
            this.dataProvider = temp;
            this.refresh();
        }
        else
        {
            trace("not dispatching");
        }
    }


    public function onTweenUpdate(value:Number):void
    {
        dropDown.scrollRect = new Rectangle(0, value, dropDown.width, dropDown.height);
    }

    public function onTweenEnd(value:Number) : void
    {     
        // Clear the scrollRect here. This way if drop shadows are
        // assigned to the dropdown they show up correctly
        dropDown.scrollRect = null;

        inTween = false;
        dropDown.enabled = true;
        dropDown.visible = showingDropdown;

        UIComponent.resumeBackgroundProcessing();
    }

    private function removedFromStage(event:Event):void
    {
        if(inTween)
        {
            openCloseTween.endTween();
        }

        // Ensure we've unregistered ourselves from PopupManager, else
        // we'll be leaked.
        PopUpManager.removePopUp(dropDown);
    }
}

}

1 голос
/ 14 марта 2011
[Bindable]
protected var _dataProvider:ArrayCollection ;

Привязка данных - это нечто уникальное для ActionScript / Flex.Среди прочего он будет отправлять события изменения.Возможно, если вы разместите свой код для пользовательского компонента, я могу быть более конкретным.

На самом деле можете ли вы объяснить, какую цель вы пытаетесь достичь?Все, что я могу сказать, это то, что вы пытаетесь сделать кнопку выпадающей.Почему?

1 голос
/ 15 марта 2011

Когда вы звоните сеттеру, вы должны убедиться, что

1) что вы на самом деле меняете значение с помощью установщика. Поэтому, даже если вы находитесь внутри класса, вызовите this.dataProvider = foo вместо _dataProvider = foo

2) Привязка не сработает, если вы фактически не измените значение. Если вы проследите, вы увидите, что установщик действительно вызывает метод получения, если значения того, что вы передаете в метод установки и получение, совпадают, привязка не произойдет.

Другой вариант - поместить событие в геттер, а затем просто вызвать его, чтобы активировать привязку.

[Bindable( "somethingChanged" )]
public function get dataProvider() : Object
{
    return _dataProvider;
}

dispatchEvent( new Event( "somethingChanged" ) );
1 голос
/ 14 марта 2011

Сделайте ваш провайдер данных привязываемым

...