2

これが私のコンポーネントのコードです:

<?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クラスには と の 2 つの継承者がTextBoxありImageBoxます。これらのクラスはすべて[Bindable]. 他のコンポーネントでは、Boxオブジェクトを選択し、このイベントについて上記のコンポーネントに通知しEventBusます。また、選択したオブジェクトを渡すためにも使用しBoxます。各TextBoxオブジェクトにはArrayCollection、使用可能なフォント サイズ (フォント) と選択されたサイズがあります。DropDownListこれらの値に 2 つの方法でバインドします。その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.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:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\formats\TextLayoutFormat.as: 628] flashx.textLayout.formats::TextLayoutFormat/set fontSize()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\formats\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] at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]

どういうわけかselectedValueのプロパティDropDownListが 0 になります。何が間違っていますか?

4

1 に答える 1

1

この実際のアプリをデバッグしないと、「ボンネットの下で」何が起こっているかを確認するのは簡単ではありません。すべてのセッターを自分でトレースして、bindibgs が発生する順序を確認できます。

私の意見では、2 つのバインディング (selectedItem と dataProvider) が同期していない可能性があるためです。どちらが最初に発生するかはわかりません。さらに重要なことに、それらの 1 つを設定すると、その drpdownlist 内で何が起こるかはわかりません。結果は、ある時点で、双方向バインディングがその時点で null である selectedItem を元に戻し、fontSize に 0 を設定することです (Number(null) が 0 であるため)。そして、その 0 は、別の場所で発生するエラーになります。

最初に fontSize セッター (trace() を入れる) で実際に設定されているものを試してみてください。

ご存知のように、双方向バインディングは良いアイデアのように思われるので、変更イベントを処理する (このイベント ハンドラーで設定を戻す) ことで、常に「従来のバインディング」に戻りました。双方向バインドを使用すると、このような問題が常に発生します。

于 2014-01-17T09:46:18.423 に答える