Flex Attention: Impossible de se lier à la propriété « foo » la classe « Object » (classe est pas un IEventDispatcher)

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

Question

J'ai un objet qui contient une douzaine de champs que je veux lier pour former des éléments, afin que je puisse utiliser cet objet pour envoyer les données au serveur pour être sauvé.

Définition de mon objet conteneur:

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 est affecté à l'exécution d'un index spécifique d'un ArrayCollection, je suis juste en utilisant l'objet emptyLink à des fins d'initialisation, la plupart du temps.

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

Bien sûr, cette compile et affiche très bien, mais il y a des avertissements d'exécution pour chaque instance:

  

avertissement: incapable de se lier à la propriété « trigger1 » la classe « Object » (classe est pas un IEventDispatcher)   Avertissement: incapable de se lier à la propriété « trigger2 » la classe « Object » (classe est pas un IEventDispatcher)   Avertissement: incapable de se lier à la propriété « Trigger3 » la classe « Object » (classe est pas un IEventDispatcher)   Avertissement: incapable de se lier à la propriété « trigger4 » la classe « Object » (classe est pas un IEventDispatcher)   Avertissement: incapable de se lier à la propriété « trigger5 » la classe « Object » (classe est pas un IEventDispatcher)

Et l'objet currentLink est pas mis à jour lorsque les champs TextInput sont modifiés.

La réponse évidente est que mon objet doit être une instance d'une classe qui implémente IEventDispatcher. Qu'est-ce que cette réponse ne me dit pas est les détails de la mise en œuvre de cette interface, et s'il y a un moyen plus simple de le faire (ce qui est nécessaire ce qui ne?) - comme un construit en classe qui se fera un plaisir d'accepter mes propriétés personnalisées et permettent pour la liaison, sans avoir à me soucier des détails de la mise en œuvre de l'interface.

Est-ce que cette classe existe? Dans le cas contraire, ce qui est la norme minimum et / ou accepté pour accomplir cette tâche?

Était-ce utile?

La solution

Vous devez utiliser ObjectProxy (comme Chetan mentionne) - mais vous devez également utiliser valueCommit pour obtenir le texte que vous entrez dans l'entrée arrière dans votre objet:

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

Autres conseils

Object ne distribuent pas d'événements. Bien que vous ayez fait la variable Bindable, les propriétés de l'objet référencé par la currentLink variable ne peut pas être lié.

Utilisez ObjectProxy à la place.

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

La première chose que vous voulez savoir est que la liaison dans Flex 3 n'est pas bidirectionnel. L'expression de liaison veillera à ce que si la source de l'expression de liaison (currentLink.trigger1) change que la cible (TextInput) recevra notification du changement et mettre à jour en conséquence. Si vous voulez la liaison aller dans l'autre sens, il y a au moins deux façons de le faire:

  1. Utilisez la balise mx: La liaison au dos TextInput.text directement à l'objet
  2. Utilisez BindingUtils pour ce faire à la place par programme.

Dans Flex 4, ils introduisent une nouvelle syntaxe pour @ {la liaison bidirectionnelle de some.binding.expression} mais ce n'est pas disponible dans Flex 3.

Sur la 2ème partie: l'erreur que vous recevez est parce que vous liez à un objet prototype « générique ». Lorsque vous appliquez le [Bindable] balise de métadonnées à une propriété ou une classe, le compilateur génère MXMLC AS code qui comprend l'utilisation des services publics et les observateurs de changement de propriété de liaison à faire faire la liaison se produise. Cependant, vous ne pouvez pas faire le prototype objet de cette car il est intégré. Vous pouvez créer une classe ActionScript personnalisée qui peut être liée (ou a certaines propriétés bindable). Le compilateur MXMLC va générer une classe qui implémente IEventDispatcher et soutient donc la liaison. Ceci a l'avantage d'être plus rapide que les objets prototypes et vous donne également la compilation de vérification, à savoir que vous recevrez une erreur de compilation si vous faites référence à une propriété non valide.

L'autre alternative consiste à envelopper votre prototype ObjectProxy comme l'un des autres membres SO a suggéré.

Juste une astuce sur la façon de trouver le code incriminé dans un projet plus vaste - mettre un point d'arrêt sur les deux

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

lignes dans la classe de SDK PropertyWatcher (Naviguer> Open Type> ...). Stacktrace alors vous aider à trouver le composant ui qui maintient la liaison rompue.

En général, la raison pour laquelle vous obtenez « incapable de se lier à la propriété foo sur une classe, est parce que vous manque soit un getter ou setter pour foo . Vous peut également foo scope à une variable publique, (bien que cela casse l'encapsulation)

Vous avez donc besoin de ces deux pour le faire disparaître:

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

ou

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

Voici les LiveDocs référence pour l'interface. Il est à peu près ce qui est évident.

Pour citer:

  

En général, la meilleure façon pour une classe définie par l'utilisateur pour obtenir des fonctions de distribution est d'étendre EventDispatcher.

Par conséquent,

  

const private static emptyLink: EventDispatcher = {

Je n'utilise Flex très longtemps, et cela pourrait ne pas répondre à vos besoins, mais pourquoi ne pas utiliser XML? Je crois que vous pouvez définir la valeur de texte TextInput aux attributs dans le fichier XML.

J'utilise pseudo-code, mais quelque chose comme cela a du sens pour moi:

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

Quelque chose comme ça, peut-être?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top