Attenzione Flex: Impossibile collegarsi alla proprietà 'pippo' sulla classe 'Oggetto' (classe non è un IEventDispatcher)

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

Domanda

Ho un oggetto che contiene una dozzina di campi che voglio legare per formare gli elementi, in modo che possa utilizzare quell'oggetto per inviare i dati al server per essere salvato.

Definizione del mio oggetto contenitore:

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 è assegnato in fase di esecuzione ad un indice specifico da un ArrayCollection, sto solo utilizzando l'oggetto emptyLink a fini di inizializzazione, per lo più.

<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>

Naturalmente, questo compila e visualizza bene, ma ci sono avvertimenti di runtime per ogni istanza:

  

Attenzione: incapace di legare alla proprietà 'Trigger1' sulla classe 'Oggetto' (classe non è un IEventDispatcher)   Avviso: impossibile associare alla proprietà 'Trigger2' sulla classe 'Oggetto' (classe non è un IEventDispatcher)   Avviso: impossibile associare alla proprietà 'Trigger3' sulla classe 'Oggetto' (classe non è un IEventDispatcher)   Avviso: impossibile associare alla proprietà 'trigger4' sulla classe 'Oggetto' (classe non è un IEventDispatcher)   Avviso: impossibile associare alla proprietà 'trigger5' sulla classe 'Oggetto' (classe non è un IEventDispatcher)

E l'oggetto currentLink non viene aggiornato quando i campi TextInput vengono modificati.

La risposta ovvia è che il mio oggetto deve essere un'istanza di una classe che implementa IEventDispatcher. Quello che la risposta non mi dice è i particolari di attuazione di tale interfaccia, e se c'è un modo più semplice per fare questo (ciò che è necessario cosa non lo è?) - come un costruito in classe che accetta volentieri le mie proprietà personalizzate e consentire per il legame, senza di me doversi preoccupare i particolari che implementa l'interfaccia.

Esiste un tale classe esiste? Se no, qual è il minimo indispensabile e / o standard accettato per realizzare questo compito?

È stato utile?

Soluzione

È necessario utilizzare ObjectProxy (come cita Chetan) - ma è anche necessario utilizzare valueCommit per ottenere il testo immesso nell'input di nuovo nella vostra oggetto:

<?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>

Altri suggerimenti

Object non invia eventi. Anche se avete fatto la variabile Bindable, le proprietà dell'oggetto a cui fa riferimento il currentLink variabile non può essere vincolato.

Usa ObjectProxy invece.

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

La prima cosa che si vorrà sapere è che il legame di Flex 3 non è bidirezionale. L'espressione vincolante farà in modo che se la fonte dell'espressione di legame (currentLink.trigger1) cambia che la porta (TextInput) riceve la notifica della modifica e aggiornare di conseguenza. Se si desidera che il legame di andare nella direzione opposta, ci sono almeno due modi per farlo:

  1. Utilizza il mx: Legatura tag per dirigere TextInput.text tornare all'oggetto
  2. BindingUtils per fare questo a livello di codice, invece.

In Flex 4 si stanno introducendo una nuova sintassi per bidirezionale @ {} some.binding.expression vincolante ma non è disponibile in Flex 3.

Al 2 ° parte: l'errore che si sta ricevendo è perché si sono vincolanti ad un "generico" prototipo oggetto. Quando si applica il [Bindable] tag di metadati a una proprietà o di classe, il compilatore genera mxmlc AS codice che include l'uso di utility di legame e gli osservatori del cambiamento di proprietà per fare rendere il legame accada. Tuttavia non è possibile effettuare il prototipo dell'oggetto fare questo dal momento che è un built-in. È possibile creare una classe ActionScript personalizzato che è associabile (o ha alcune proprietà associabile). Il compilatore mxmlc genererà una classe che implementa IEventDispatcher e sostiene pertanto vincolante. Questo ha il vantaggio di essere più veloce di oggetti prototipo e ti dà in fase di compilazione, vale a dire si riceverà un errore di compilazione, se si fa riferimento a una proprietà non valida anche.

L'altra alternativa è quella di avvolgere il vostro prototipo nel ObjectProxy come uno degli altri SO membri ha suggerito.

Solo un consiglio su come trovare il codice incriminato in un progetto più ampio - mettere un punto di interruzione sulla due

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

linee nella classe PropertyWatcher del SDK (Naviga> Open Type> ...). Stacktrace sarà quindi aiuterà a trovare il componente dell'interfaccia utente che contiene il rotto vincolante.

In generale, il motivo per cui si ottiene "in grado di legarsi alla proprietà foo su una classe, è perché o si è manca un getter o setter per foo . potrebbe anche fare foo ambito di una variabile pubblica, (anche se questo si rompe incapsulamento)

Quindi è necessario Entrambi questi per farlo andare via:

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

o

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

Ecco il LiveDocs riferimento per l'interfaccia. E 'più o meno quello che sarebbe stato ovvio.

Per citare:

  

In generale, il modo più semplice per una classe definita dall'utente per acquisire funzioni di invio degli eventi è quello di estendere EventDispatcher.

Quindi,

  

const private static emptyLink: EventDispatcher = {

Non ho usato Flex per molto tempo, e questo potrebbe non soddisfare le vostre esigenze, ma perché non usare XML? Credo che si può impostare il valore di testo TextInput attributi in XML.

sto usando pseudo-codice, ma qualcosa di simile ha senso per me:

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

Qualcosa di simile, forse?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top