双向数据绑定问题

时间:2014-01-11 12:52:10

标签: actionscript-3 flash flex data-binding 2-way-object-databinding

这是我的组件代码:

<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   width="950" height="50" creationComplete="this_creationCompleteHandler(event)"
                   currentState="default" enabled="{currentBox!=null}">
    <s:states>
        <s:State name="default"/>
        <s:State name="boxSelected" stateGroups="admin"/>
        <s:State name="textBoxSelected" stateGroups="user"/>
        <s:State name="imageBoxSelected" stateGroups="user"/>
    </s:states>
    <s:layout>
        <s:HorizontalLayout gap="10" horizontalAlign="left" paddingBottom="10" paddingLeft="10"
                            paddingRight="10" paddingTop="10" verticalAlign="middle"/>
    </s:layout>

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            public var model:Model;

            private var _currentBox:Box = null;
            [Bindable]
            public function set currentBox(box:Box):void 
            {
                _currentBox = box;
                if(model.userType == Model.USER_TYPE_ADMIN)
                    currentState = "boxSelected";
                else if(box is TextBox)
                    currentState = "textBoxSelected";
                else if(box is ImageBox)
                    currentState = "imageBoxSelected";
                else
                    currentState = "default";
            }

            public function get currentBox():Box
            {
                return _currentBox;
            }

            protected function this_creationCompleteHandler(event:FlexEvent):void
            {
                AppEventBus.instance.addListener(AppEvent.BOX_SELECTED, boxSelectedHandler);
                AppEventBus.instance.addListener(AppEvent.PAGE_SELECTED, pageSelectedhandler);
            }

            protected function boxSelectedHandler(event:AppEvent):void
            {
                currentBox = event.data as Box;
            }

            protected function pageSelectedhandler(event:AppEvent):void
            {
                currentBox = null;
            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:ToggleButton id="secureLockButton" includeIn="admin, user" width="20" height="20"
                    selected="@{currentBox.secured}"
                    styleName="secureButtonStyle"/>
    <s:DropDownList id="fontsList" includeIn="textBoxSelected" width="150" height="20"
                    selectedItem="@{(currentBox as TextBox).font}"
                    dataProvider="{(currentBox as TextBox).fonts}"/>
    <s:DropDownList id="fontSizesList" includeIn="textBoxSelected" width="60" height="20"
                    selectedItem="@{(currentBox as TextBox).fontSize}"
                    dataProvider="{(currentBox as TextBox).fontSizes}"/>
    <s:DropDownList id="boxTypes" includeIn="boxSelected" width="70" height="20"
                    dataProvider="{Box.BOX_TYPES}" selectedItem="{currentBox.boxType}"/>
    <s:TextInput id="boxName" includeIn="boxSelected" width="70" height="20"
                 text="@{currentBox.name}"/>
</s:BorderContainer>

Box类有两个继承者:TextBoxImageBox。所有这些类都是[Bindable]。在另一个组件中,我选择了Box个对象,并通过EventBus将上述组件通知此事件。我也用它来传递选定的Box对象。每个TextBox对象都有ArrayCollection个可用的字体大小(字体)和一个选定的字体。我希望以两种方式将DropDownList绑定到这些值。因此DropDownList始终显示当前所选的字体大小(字体),如果用户从列表中选择另一个值,则将其设置为当前TextBox对象。

当我第一次选择TextBox对象时一切正常但是当我选择另一个时我得到错误:

  

RangeError:属性fontSize值0超出范围       在flashx.textLayout.property::Property$/defaultErrorHandler()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\property\Property.as:31]       在flashx.textLayout.property::Property/setHelper()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\property\Property.as:230]       在flashx.textLayout.formats :: textLayoutFormat中/ setStyleByProperty()[C:\牛皮纸\分支\ V2 \ 2.0 \ dev的\输出\ OPENSOURCE \ TextLayout中\ SRC \ flashx \ TextLayout中\格式\ TextLayoutFormat.as:628]       在flashx.textLayout.formats :: textLayoutFormat中/置fontSize的()[C:\牛皮纸\分支\ V2 \ 2.0 \ dev的\输出\ OPENSOURCE \ TextLayout中\ SRC \ flashx \ TextLayout中\格式\ TextLayoutFormat.as:1044]       在spark.core :: CSSTextLayoutFormat()[E:\ dev \ 4.y \ frameworks \ projects \ spark \ src \ spark \ core \ CSSTextLayoutFormat.as:75]       在spark.components :: RichEditableText / updateStylesIfChanged()[E:\ dev \ 4.y \ frameworks \ projects \ spark \ src \ spark \ components \ RichEditableText.as:3649]       在spark.components :: RichEditableText / commitProperties()[E:\ dev \ 4.y \ frameworks \ projects \ spark \ src \ spark \ components \ RichEditableText.as:2509]       在mx.core :: UIComponent / validateProperties()[E:\ dev \ 4.y \ frameworks \ projects \ framework \ src \ mx \ core \ UIComponent.as:8219]       在mx.managers :: LayoutManager / validateProperties()[E:\ dev \ 4.y \ frameworks \ projects \ framework \ src \ mx \ managers \ LayoutManager.as:597]       在mx.managers :: LayoutManager / doPhasedInstantiation()[E:\ dev \ 4.y \ frameworks \ projects \ framework \ src \ mx \ managers \ LayoutManager.as:813]       在mx.managers :: LayoutManager / doPhasedInstantiationCallback()[E:\ dev \ 4.y \ frameworks \ projects \ framework \ src \ mx \ managers \ LayoutManager.as:1180]

不知何故selectedValue DropDownList的{​​{1}}属性变为0.我做错了什么?

1 个答案:

答案 0 :(得分:1)

在没有调试这个实际应用程序的情况下,很难看到“引擎盖下”发生了什么。您可以自己跟踪所有setter,以查看bindibgs发生的顺序。

因为在我看来,可能是hapenning的是两个绑定(selectedItem和dataProvider) - 不是你想要的同步。你永远不知道哪一个会先发生,更重要的是,当你设置其中一个时,在该drpdownlist中会发生什么。结果是,在一点上,双向绑定设置了selectedItem,当时为null,并将0设置为fontSize(因为Number(null)为0)。而那个0会导致错误发生在其他地方。

只需尝试在fontSize setter中设置的内容(在其中放置一个trace())即可。

你知道,因为双向绑定似乎是个好主意,所以我总是以处理更改事件(在此事件处理程序中设置)结束回“经典绑定”。在使用双向绑定时,我们总是遇到类似于这个问题。