Apache flex 手动分派集合更改事件

Apache flex 手动分派集合更改事件,apache-flex,actionscript,flex4,Apache Flex,Actionscript,Flex4,我有一个标准的组合框,当数据提供程序完成初始化时,它会分派一个收集事件: my_cb.addEventListener CollectionEvent.COLLECTION_更改,getMyStuff 然后我有一个自定义组件,它也有一个数据提供者。我如何让它在数据提供程序完成加载时调度集合更改事件 据我所知,我做不到。调度propertychangeevent是否有效 谢谢你的建议 更新: 我有一个自定义组件,我称之为“SortingComboBox”,但它根本不是一个ComboBox;它扩展了

我有一个标准的组合框,当数据提供程序完成初始化时,它会分派一个收集事件:

my_cb.addEventListener CollectionEvent.COLLECTION_更改,getMyStuff

然后我有一个自定义组件,它也有一个数据提供者。我如何让它在数据提供程序完成加载时调度集合更改事件

据我所知,我做不到。调度propertychangeevent是否有效

谢谢你的建议

更新:

我有一个自定义组件,我称之为“SortingComboBox”,但它根本不是一个ComboBox;它扩展了按钮,我将is dataProvider属性设置为我的arraycollection,model.product,它是arraycollection

下面是我如何在该组件中使用数据提供程序:

代码

[可装订] 私有var_数据提供者:对象

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

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

    }
代码

在该组件的createChildren方法中,我使用以下方法:

BindingUtils.bindPropertydropDown,数据提供程序,此,数据提供程序


下拉列表是我用来显示标签的自定义VBox

使数据提供程序可绑定

使数据提供程序可绑定

[Bindable]
protected var _dataProvider:ArrayCollection ;
数据绑定是ActionScript/Flex独有的功能。 除其他事项外,它将发送更改事件。 也许如果你发布自定义组件的代码,我可以更具体一些。

你能解释一下你的目标是什么吗? 我所能说的就是你想让一个按钮有一个下拉列表。 为什么?

数据绑定是ActionScript/Flex独有的功能。 除其他事项外,它将发送更改事件。 也许如果你发布自定义组件的代码,我可以更具体一些。

你能解释一下你的目标是什么吗? 我所能说的就是你想让一个按钮有一个下拉列表。
为什么?

当你打电话给设定者时,你必须确保

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

当你打电话给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" ) );

这是一个定制组件,只是为了给你一个更好的想法

代码 包com.fidelity.primeservices.act.components.sortingcombobox { 导入com.fidelity.primeservices.act.events.component.ResetSortEvent; 导入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);
    }
}

}

这是一个定制组件,旨在为您提供更好的想法

代码 包com.fidelity.primeservices.act.components.sortingcombobox { 导入com.fidelity.primeservices.act.events.component.ResetSortEvent; 导入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);
    }
}
}

确定此处的代码

[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是没有意义的。 另一方面,您将源_数据提供程序设置为可绑定的,因此每当数据更改时,它都会发送CollectionEvent.COLLECTION_更改

确定此处的代码

[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是没有意义的。 另一方面,您将源_数据提供程序设置为可绑定的,因此每当数据更改时,它都会发送CollectionEvent.COLLECTION_更改

setter是可绑定的,因为我通过以下方式保护它:\ u dataProvider。让我更具体一点:我对自定义组件使用ArrayCollection,但它不是真正的数据提供程序;也就是说,我将其转换为使用标签的对象。也就是说,我真正的问题是如何在ArrayCollection加载后捕获事件。CollectionEvent在每次添加新项时广播一个ADD事件,但我需要知道所有项何时都在。setter是可绑定的,因为我通过以下方式保护它:_dataProvider。让我更具体一点:我对自定义组件使用ArrayCollection,但它不是真正的dataProvider;也就是说,我将其转换为使用标签的对象。也就是说,我真正的问题是如何在ArrayCollection加载后捕获事件。C
每当添加一个新项目时,CollectionEvent都会广播一个ADD事件,但我需要知道所有项目何时都在。目标是创建一个combobox组件,允许用户使用复选框选择多个选项。我从我接管的项目中继承了这个组件。在同一屏幕上,我正在使用另一个标准组合框,我监听其数据提供程序更新的方式是:this.countries\u cb.addEventListener CollectionEvent.COLLECTION\u CHANGE,getCtryIndex;我试图用这个组件做一些类似的事情。目标是制作一个combobox组件,允许用户使用复选框选择多个选项。我从我接管的项目中继承了这个组件。在同一屏幕上,我正在使用另一个标准组合框,我监听其数据提供程序更新的方式是:this.countries\u cb.addEventListener CollectionEvent.COLLECTION\u CHANGE,getCtryIndex;我试着用这个组件做一些类似的事情。好的,我知道了。谢谢你提供的非常有用的提示。我相信我已经找到了一个解决这个问题的方法,但是你的帮助一直都很有帮助。我已经接受了你的一个答案,并将其余的标记为有用,希望这会有所帮助。再次感谢。好的,我知道了。谢谢你提供的非常有用的提示。我相信我已经找到了一个解决这个问题的方法,但是你的帮助一直都很有帮助。我已经接受了你的一个答案,并将其余的标记为有用,希望这会有所帮助。再次感谢。