Problem mit der bidirektionalen Datenbindung
-
26-12-2019 - |
Frage
Hier ist der Code meiner Komponente:
<?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
Die Klasse hat zwei Erben: TextBox
Und ImageBox
.Alle diese Klassen sind [Bindable]
.In der anderen Komponente wähle ich aus Box
Objekt und benachrichtigen über dieses Ereignis die oben stehende Komponente mit EventBus
.Ich benutze es auch, um ausgewählte zu übergeben Box
Objekt.Jede TextBox
Objekt hat ArrayCollection
der verfügbaren Schriftgrößen (Fonts) und eine ausgewählte.Ich möchte meine binden DropDownList
auf diese Werte in zweierlei Hinsicht.Also DropDownList
Zeigt immer die aktuell ausgewählte Schriftgröße (Schriftart) eines Felds an. Wenn der Benutzer einen anderen Wert aus der Liste auswählt, wird dieser auf „Aktuell“ gesetzt TextBox
Objekt.
Wenn ich zum ersten Mal ein TextBox-Objekt auswähle, funktioniert alles einwandfrei, aber wenn ich ein anderes auswähle, erhalte ich die Fehlermeldung:
Bereichsfehler:Eigenschaft fontize value 0 ist außerhalb des Bereichs bei Flashx.textlayout.property::Property$/defaulterrorhandler () [c: vellum ails v2 2.0 dev output openSource textLayout src flashx textLayout Property.as:31] unter FlashX.TextLayout.property::property/sethelper()..- : 230] bei Flashx.TextLayout.Formats :: textLayoutFormat/setStylebyProperty () [c: vellum aies v2 2.0 dev output openSource textLayout src flasx textlayout formats textLay. unter flashx.textlayout.Formats :: textLayoutFormat/set fontSize () [c: vellum disies v2 2.0 dev output openSource textLayout src flashx textLayout formats textFormat.as: 1044] at lich .core :: csStextLayoutFormat () [e: dev 4.y Frameworks Projects Spark Src Spark Core csStextLayoutFormat.as: 75] AT Spark.comPonents :: RicheDitableText/updatSifchanged () [E: dev 4.y Frameworks Projects Spark Src Spark Komponenten RichEDitableText.as: 3649] AT Spark.comPonents :: RichEDitableText/commesenthProperties () [E: dev 4.y Frameworks projects projects projecing src spark components RicheDitableText.as: 2509] at mx.core :: Uicomponent/ValateProperties () [e: dev 4.y Frameworks Projects Framework Src mx core Uicomponent.as: 8219] bei mx.Managers :: layoutManager/validateProperties () [e: dev 4.y Frameworks Projects Framework Src mx Manager layoutManager.as: 597] at mx.managers: () [E: dev 4.y Frameworks Projects Framework Src Mx Manager LayoutManager.as: 813] bei mx.managers :: layoutManager/dophasedInstantiationCallback () [E: dev 4.yyyyManager () [e: dev 4.yyymanager Frameworks Projects Framework Src MX Manager LayoutManager.as: 1180
Irgendwie selectedValue
Eigentum von DropDownList
wird 0.Was mache ich falsch?
Lösung
Es ist nicht leicht zu erkennen, was „unter der Haube“ passiert, ohne diese eigentliche App zu debuggen.Sie können alle Setter selbst verfolgen, um die Reihenfolge zu sehen, in der die Bindibgs auftreten.
Denn meiner Meinung nach könnte es passieren, dass die beiden Bindungen (selectedItem und dataProvider) nicht so synchron sind, wie Sie es wünschen.Sie wissen nie, was zuerst passiert, und was noch wichtiger ist, was in dieser Drpdownlist passiert, wenn Sie eines davon festlegen.Das Ergebnis ist, dass die bidirektionale Bindung an einem Punkt das selectedItem zurücksetzt, das zu diesem Zeitpunkt null ist, und 0 für die Schriftartgröße setzt (weil Number(null) 0 ist).Und diese 0 führt zu dem Fehler, der woanders auftritt.
Probieren Sie einfach aus, was tatsächlich im FontSize-Setter festgelegt wird (fügen Sie einen Trace() ein), um zu beginnen.
Wissen Sie, da die Zwei-Wege-Bindung eine gute Idee zu sein scheint, bin ich immer zur „klassischen Bindung“ zurückgekehrt und habe das Änderungsereignis behandelt (in diesem Ereignishandler zurückgesetzt).Bei der Verwendung der bidirektionalen Bindung sind wir immer auf ein ähnliches Problem gestoßen.