手动调度集合更改事件

时间:2011-03-14 19:16:05

标签: flex actionscript flex4

我有一个标准组合框,在dataprovider完成初始化时调度一个集合事件:

my_cb.addEventListener(CollectionEvent.COLLECTION_CHANGE,getMyStuff);

然后我有一个也有dataProvider的自定义组件。如何在dataprovider完成加载时调度集合更改事件?

从我读过的内容来看,我做不到。是否会调度propertychangeevent工作?

感谢您提供任何有用的提示!

更新:

我有一个自定义组件,我称之为'SortingComboBox',但它根本不是ComboBox;它扩展了Button,我将dataProvider属性设置为我的arraycollection,model.product(这是一个数组集合)。

以下是我在该组件中使用dataProvider的方法:

code

[绑定] private 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 个答案:

答案 0 :(得分:1)

使您的数据提供者可绑定

答案 1 :(得分:1)

[Bindable]
protected var _dataProvider:ArrayCollection ;

数据绑定是ActionScript / Flex独有的功能 除其他外,它将派遣变革事件 也许如果您发布自定义组件的代码,我可以更具体

实际上,您能解释一下您的目标是什么吗? 我只能告诉你,你正试图让一个按钮下拉 为什么呢?

答案 2 :(得分:1)

当你打电话给setter时,你必须确保

1)您实际上是使用setter更改值。因此,即使您在课堂内,也请调用this.dataProvider = foo而不是_dataProvider = foo

2)除非您实际更改了值,否则不会触发绑定。如果你跟踪你会看到setter实际上调用了getter,如果传入setter和getter的值相同,则不会发生绑定。

你的另一个选择是在getter上放一个事件,然后调用它来触发绑定。

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

dispatchEvent( new Event( "somethingChanged" ) );

答案 3 :(得分:1)

这是自定义组件,只是为了让您有更好的想法。

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);
    }
}

}

答案 4 :(得分:1)

这里的代码好了

[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;

由于对象是通过引用传递的,所以无论如何都不会保护它,并且setter和getter是没有意义的。
另一方面,您创建了源_dataProvider Bindable,因此无论何时数据发生更改,它都会调度CollectionEvent.COLLECTION_CHANGE