Flex-Warnung:Bindung an die Eigenschaft „foo“ der Klasse „Object“ nicht möglich (Klasse ist kein IEventDispatcher)

StackOverflow https://stackoverflow.com/questions/928081

Frage

Ich habe ein Objekt, das etwa ein Dutzend Felder enthält, die ich an Formularelemente binden möchte, damit ich dieses Objekt verwenden kann, um die Daten zum Speichern an den Server zurückzusenden.

Definition meines Containerobjekts:

private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:Object = emptyLink;

currentLink zur Laufzeit einem bestimmten Index aus einer ArrayCollection zugewiesen wird, verwende ich nur die emptyLink Objekt hauptsächlich für Initialisierungszwecke.

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
    <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
        <mx:TextInput id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" />
        <mx:TextInput id="trigger2" width="100%" textAlign="left" text="{currentLink.trigger2}" />
        <mx:TextInput id="trigger3" width="100%" textAlign="left" text="{currentLink.trigger3}" />
        <mx:TextInput id="trigger4" width="100%" textAlign="left" text="{currentLink.trigger4}" />
        <mx:TextInput id="trigger5" width="100%" textAlign="left" text="{currentLink.trigger5}" />
    </mx:VBox>
</mx:Panel>

Natürlich lässt sich das problemlos kompilieren und anzeigen, aber es gibt Laufzeitwarnungen für jede Instanz:

Warnung:Es kann nicht an die Eigenschaft 'Trigger1' auf der Klasse 'Objekt' binden (Klasse ist keine IeventDispatcher) Warnung:Es kann nicht an die Eigenschaft 'Trigger2' auf der Klasse 'Objekt' binden (Klasse ist keine IeventDispatcher) Warnung:Es kann nicht an die Eigenschaft 'Trigger3' auf der Klasse 'Objekt' binden (Klasse ist keine IeventDispatcher) Warnung:Es kann nicht an die Eigenschaft 'Trigger4' auf der Klasse 'Objekt' binden (Klasse ist keine IeventDispatcher) Warnung:Bindung an die Eigenschaft „trigger5“ der Klasse „Object“ nicht möglich (Klasse ist kein IEventDispatcher)

Und das currentLink Das Objekt wird nicht aktualisiert, wenn das TextInput Felder werden geändert.

Die offensichtliche Antwort ist, dass mein Objekt eine Instanz einer Klasse sein muss, die es implementiert IEventDispatcher.Was mir diese Antwort nicht sagt, sind die Einzelheiten der Implementierung dieser Schnittstelle (was ist erforderlich?was nicht?), und ob es einen einfacheren Weg gibt, dies zu tun – etwa eine eingebaute Klasse, die gerne meine benutzerdefinierten Eigenschaften akzeptiert und eine Bindung zulässt, ohne dass ich mich um die Einzelheiten der Implementierung der Schnittstelle kümmern muss.

Gibt es eine solche Klasse?Wenn nicht, was ist das absolute Minimum und/oder der akzeptierte Standard für die Erfüllung dieser Aufgabe?

War es hilfreich?

Lösung

Sie müssen Object verwenden (wie Chetan Nennungen) - aber Sie müssen auch valueCommit verwenden, um den Text, den Sie in dem Eingang zurück in Ihr Objekt eingeben zu bekommen:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectProxy;
              private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);


private function handleClick():void
{
    trace(currentLink.trigger1);
}
]]>
</mx:Script>

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
        <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput  id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" valueCommit="{currentLink.trigger1 = trigger1.text;}"/>

                <mx:Button label="Click" click="handleClick()"/>
        </mx:VBox>
</mx:Panel>        

</mx:WindowedApplication>

Andere Tipps

Object keine Ereignisse versenden. Obwohl Sie die Variable Bindable gemacht haben, können Sie die Eigenschaften des Objekts durch die Variable currentLink referenziert nicht gebunden werden.

Verwenden ObjectProxy statt.

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);

Das Erste, was Sie wissen möchten, ist, dass die Bindung in Flex 3 nicht bidirektional ist.Der Bindungsausdruck stellt sicher, dass bei einer Änderung der Quelle des Bindungsausdrucks (currentLink.trigger1) das Ziel (TextInput) eine Benachrichtigung über die Änderung erhält und entsprechend aktualisiert wird.Wenn die Bindung in die andere Richtung erfolgen soll, gibt es mindestens zwei Möglichkeiten:

  1. Verwenden Sie das Tag mx:Binding, um TextInput.text zurück zum Objekt zu leiten
  2. Verwenden Sie stattdessen BindingUtils, um dies programmgesteuert zu tun.

In Flex 4 führen sie eine neue Syntax für die bidirektionale Bindung @{some.binding.expression} ein, die jedoch in Flex 3 nicht verfügbar ist.

Zum 2. Teil:Der Fehler, den Sie erhalten, liegt daran, dass Sie an ein „generisches“ Prototypobjekt binden.Wenn Sie das Metadaten-Tag [Bindable] auf eine Eigenschaft oder Klasse anwenden, generiert der MXMLC-Compiler AS-Code, der die Verwendung von Bindungsdienstprogrammen und Eigenschaftsänderungsbeobachtern umfasst, um die Bindung durchzuführen.Sie können das Prototypobjekt jedoch nicht dazu veranlassen, dies zu tun, da es ein integriertes Objekt ist.Sie können eine benutzerdefinierte ActionScript-Klasse erstellen, die bindbar ist (oder über bestimmte bindbare Eigenschaften verfügt).Der MXMLC-Compiler generiert eine Klasse, die IEventDispatcher implementiert und daher die Bindung unterstützt.Dies hat den Vorteil, dass es schneller als Prototypobjekte ist und Ihnen auch eine Überprüfung zur Kompilierungszeit ermöglicht, d. h.Sie erhalten einen Compilerfehler, wenn Sie auf eine ungültige Eigenschaft verweisen.

Die andere Alternative besteht darin, Ihren Prototyp in ObjectProxy zu verpacken, wie eines der anderen SO-Mitglieder vorgeschlagen hat.

Nur ein Tipp, wie man in einem größeren Projekt, um den fehlerhaften Code, um herauszufinden, - setzen Sie einen Haltepunkt auf den beide

trace("warning: unable to bind to property '"

Zeilen in den SDK PropertyWatcher Klasse (Navigieren> Open Type> ...). Stacktrace wird Ihnen dann helfen, die UI-Komponente zu finden, die die Bindung gebrochen hält.

Im Allgemeinen ist der Grund, warum Sie „nicht in der Lage zu binden Eigenschaft foo auf eine Klasse bekommen, ist, weil Sie entweder einen Getter oder Setter für foo fehlt . Sie könnte auch foo scoped auf eine öffentliche Variable machen, (obwohl diese Verkapselung bricht)

So Sie beide müssen es weggehen:

public function set foo (o:FooObject) : void {
...
}

oder

public function get foo() : FooObject {
...
}

Hier ist die LiveDocs für die Schnittstelle Referenz . Es ist ziemlich viel, was offensichtlich ist.

Zitat:

  

Im Allgemeinen ist der einfachste Weg für eine benutzerdefinierte Klasse Event Dispatching Fähigkeiten zu gewinnen ist Eventdispatcher zu verlängern.

So

  

privat static const emptyLink: Eventdispatcher = {

Ich habe nicht Flex wurde unter Verwendung von sehr lange, und dies könnte Ihre Anforderungen nicht passen, aber warum nicht XML verwenden? Ich glaube, dass Sie den TextInput- Textwert auf Attribute in der XML festlegen können.

Ich bin mit Pseudo-Code, aber so etwas wie dies macht Sinn für mich:

[Bindable] private static const currentLink:XML = <root>
                                                    <trigger1 value=""/>
                                                    <trigger2 value="" />
                                                  </root>;
...
<mx:TextInput id="trigger1" width ... text="{currentLink.trigger1.@value}" />

So etwas wie dies vielleicht?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top