2009-05-29 17 views
22

Ho un oggetto che contiene una dozzina di campi che voglio associare per formare elementi, in modo che io può usare quell'oggetto per inviare i dati al server da salvare.Flex Avvertenza: impossibile associare alla proprietà 'pippo' sulla classe 'Oggetto' (la classe non è un IEventDispatcher)

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 avvisi di runtime per ogni istanza:

avvertimento: in grado di legarsi alle cose 'Trigger1' sulla classe 'Oggetto' (classe è non un IEventDispatcher) Avviso : impossibile eseguire il binding alla proprietà 'trigger2' sulla classe 'Object' (la classe non è un IEventDispatcher) Avviso : impossibile eseguire il binding alla proprietà 'trigger3' sulla classe 'Object' (la classe non è un IEventDispatcher) Avviso : impossibile eseguire il binding alla proprietà 'trigger4' sulla classe 'Object' (la classe non è un IEventDispatcher) avvertimento: incapace di legare alla proprietà 'trigger5' on 'Oggetto' di classe (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. Ciò che questa risposta non mi dice sono i dettagli dell'implementazione di quell'interfaccia (cosa è richiesto? Cosa non lo è?), E se c'è un modo più semplice per farlo, come una classe integrata che accetterà volentieri le mie proprietà personalizzate e consentirà per il binding, senza che io debba preoccuparmi dei particolari di implementazione dell'interfaccia.

Esiste una classe simile? In caso contrario, qual è lo standard minimo e/o accettato per eseguire questa attività?

risposta

15

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

Non uso Flex da molto tempo, e questo potrebbe non essere adatto alle vostre esigenze, ma perché non usare XML? Credo che tu possa impostare il valore del testo TextInput sugli attributi nel codice XML.

che 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="{[email protected]}" /> 

Qualcosa di simile, forse?

8

Object non invia eventi. Sebbene sia stata creata la variabile Bindable, non è possibile associare le proprietà dell'oggetto a cui fa riferimento la variabile currentLink.

Utilizzare invece ObjectProxy.

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

Here's the livedocs reference per l'interfaccia. È praticamente ciò che sarebbe 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,

static const privato emptyLink: EventDispatcher = {

+0

il tuo link non va alla pagina all'interno dei livedocs che hai pensato di fare. Ogni pagina di riferimento di livedocs ha un "Link corrente: ..." nel suo piè di pagina, con l'URL per il collegamento diretto della pagina che stai visualizzando. Usalo. :) –

4

La prima cosa che si vorrà sapere è che il legame di Flex 3 non è bidirezionale. L'espressione di associazione garantirà che se l'origine dell'espressione di associazione (currentLink.trigger1) cambia che la destinazione (TextInput) riceverà la notifica della modifica e l'aggiornamento di conseguenza. Se si desidera che il legame di andare nella direzione opposta, ci sono almeno due modi per farlo:

  1. Utilizzare i mx: Legatura tag per dirigere TextInput.text tornare all'oggetto
  2. Usa BindingUtils fare questo invece programmaticamente.

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 sta vincolando a un oggetto prototipo "generico". Quando si applica il tag metadata [Bindable] a una proprietà o classe, il compilatore MXMLC genera un codice AS che include l'uso di utilità di associazione e osservatori di modifiche delle proprietà per fare in modo che l'associazione avvenga. Tuttavia non è possibile rendere il prototipo Object come questo poiché è un built-in. È possibile creare una classe ActionScript personalizzata che sia associabile (o che abbia determinate proprietà associabili). Il compilatore MXMLC genererà una classe che implementa IEventDispatcher e quindi supporta l'associazione. Questo ha il vantaggio di essere più veloce degli oggetti prototipo e offre anche un controllo in fase di compilazione, cioè riceverai un errore del compilatore se fai riferimento a una proprietà non valida.

L'altra alternativa è avvolgere il tuo prototipo in ObjectProxy come uno degli altri membri SO ha suggerito.

+0

Se potessi accettare 2 risposte, questa sarebbe la # 2. Ho scelto Gabriel's perché era la soluzione più semplice per fare quello che sto tentando di fare. Grazie per tutte le informazioni, però! –

1

In generale, il motivo per cui si ottenere "incapace di legare alla proprietà pippo su una classe, è perché si manca un getter o setter per pippo.Si potrebbe anche fare foo ambito di una variabile pubblica, (anche se questo si rompe l'incapsulamento)

quindi è necessario Entrambi questi per farlo andare via:

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

o

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

Solo un suggerimento su come scoprire il codice incriminato in un progetto più ampio - inserire un punto di interruzione sui due

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

righe nella classe PropertyWatcher dell'SDK (Naviga> Tipo aperto> ...). Stacktrace ti aiuterà quindi a trovare il componente ui che contiene la rilegatura rotta.

Problemi correlati