2009-06-01 8 views
0

Je réécris un rendu d'élément MXML en pur AS. Un problème que je n'arrive pas à résoudre est comment faire en sorte que chaque rendu d'élément réagisse à une modification sur une propriété statique de la classe de rendu d'élément. Dans la version MXML, je l'après liaison mis en place sur l'élément moteur de rendu:Réagir pour modifier une propriété statique

instanceProperty={callInstanceFunction(ItemRenderer.staticProperty)} 

Quelle serait la façon équivalente de cette mise en place dans AS (en utilisant BindingUtils, je suppose)?

MISE À JOUR:
donc je pensais que ce qui suit ne fonctionnait pas, mais il semble que Flex réprime les erreurs jetées dans le instanceFunction, faisant apparaître comme si la liaison elle-même est mauvais.

BindingUtils.bindSetter(instanceFunction, ItemRenderer, "staticProperty"); 

Toutefois, lorsque instanceFunction est appelée, les variables déjà initialisés sur l'instance donnée sont tous nuls, ce qui était la cause des erreurs mentionnées ci-dessus. Des idées pourquoi c'est?

Répondre

2

Vous avez 2 options que je suis au courant:

Option 1 Vous pouvez creuser dans le code que le compilateur flex builds basé sur votre MXML pour voir comment il gère la liaison aux propriétés statiques. Il existe une directive de compilateur appelée -keep-generated-actionscript qui fera que les fichiers générés resteront. Tout ce qui se passe à travers ceux-ci peut vous donner une idée de ce qui se passe. Cette option implique l'instanciation des objets Binding et des objets StaticPropertyWatcher.

Option 2 Il est objet staticEventDispatcher qui est ajoutée à la compilation des classes contenant des variables statiques voir ce post http://thecomcor.blogspot.com/2008/07/adobe-flex-undocumented-buildin.html. Selon la publication, cet objet est ajouté uniquement en fonction de la présence de variables statiques et non de fonctions getter.

Exemple de l'option 2 Disons que nous avons une classe nommée MyClassContainingStaticVariable avec une variable statique nommée MyStaticVariable et un autre someobject.somearrayproperty variable que nous voulons obtenir mis à jour chaque fois que des changements MyStaticVariable.

Class(MyClassContainingStaticVariable).staticEventDispatcher.addEventListener(
PropertyChangeEvent.PROPERTY_CHANGE, 
function(event:PropertyChangeEvent):void 
{ 
    if(event.property == "MyStaticVariable") 
    { 
     someobject.somearrayproperty = event.newValue as Array; 
    } 
}); 
+0

sympa! Flash Builder n'effectue même pas de saisie semi-automatique pour Class :: staticEventDispatcher(), mais cela fonctionne – sydd

+0

Oui, en fonction du post référencé, je pense qu'il est ajouté au moment de la compilation, donc pas réellement disponible pour l'auto complet pendant le codage. – bingles

+0

@bingles Des choses très intéressantes! Il y a bien longtemps que je suis passé à autre chose, mais c'est un beau travail de creuser ça. – Stiggler

0

Je pense que vous devez répondre à l'événement "PropertyChanged".

+0

Pouvez-vous élaborer un peu? Comment/quand cet événement est-il distribué? – Stiggler

0

Si vous allez faire cela, utilisez un singleton au lieu de statique. Je ne pense pas que ça va marcher sur un statique. (Si vous devez le faire de cette façon, il y a probablement deux façons de le faire, ce qui serait préférable).

var instance:ItemRenderer = ItemRenderer.getInstance(); 
BindingUtils.bindProperty(this, "myProperty", instance, "theirProperty"); 
+0

Désolé, mais je ne cherche pas une approche différente, car celle-ci semble fonctionner en MXML. Je m'interroge sur le travail qui se passe dans les coulisses. – Stiggler

+0

Eh bien, la liaison met en place des écouteurs d'événement pour les propriétés. Vous ne pouvez pas écouter un objet de classe, car ce n'est pas un EventDispatcher. Vous pourriez le faire si votre classe étendait EventDispatcher et que vous utilisiez la méthode singleton. Aussi mauvais que puisse être le singleton, les classes statiques sont les pires. Cela pourrait fonctionner en MXML, mais cela n'est certainement pas lié. Il pourrait juste trouver la valeur une fois et ne jamais mettre à jour après cela. –

+0

J'apprécie votre temps, mais il semble que nous ne soyons pas sur la même longueur d'onde. Tout d'abord, je cherche à faire cela pour un ItemRenderer, ce qui implique que la classe aura plusieurs instances, excluant immédiatement toute utilisation d'un singleton, pour le meilleur ou pour le pire. Deuxièmement, la liaison aux propriétés statiques est autorisée, tant que ce n'est pas un getter/setter statique. La liaison que j'ai configurée dans MXML ne fonctionne pas seulement une fois, mais 100% du temps. – Stiggler

0

Après tripoter pendant un certain temps, je conclus que ce n'est pas possible dans ActionScript, pas même avec bindSetter. Il semble qu'il y ait quelques fonctionnalités MXML uniquement des liaisons de données à en juger par l'extrait suivant des documents Adobe (mais n'est-il pas tout compilé en code AS de toute façon)?

On ne peut pas inclure des fonctions ou réseau éléments dans les chaînes de propriété dans une expression liaison de données défini par le procédé bindProperty() ou bindSetter(). Pour plus d'informations sur les propriétés chaînes, voir Travailler avec des chaînes de propriétés pouvant être liées.

Source: http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_7.html

0

Vous pouvez créer une classe HostProxy à se substituer à l'appel funciton. Un peu comme une classe HostFunctionProxy qui s'étend de proxy, et a un getProperty("functionInvokeStringWithParameters") qui invoquera la fonction à distance de l'hôte, et enverra un événement "change" pour déclencher la liaison dans une classe Proxy [Bindable("change")] typique.

Vous laissez la classe HostProxy agir en tant qu'hôte et vous utilisez la propriété pour déclencher à distance l'appel de fonction. Bien sûr, il serait plus cool d'avoir quelques TypeHelperUtil pour permettre de convertir des valeurs de chaîne brutes en valeurs de type sérialisé à l'exécution pour les paramètres de méthode (séparés par des virgules en général). Par exemple:

var standInHost:Object = new HostFunctionProxy(someModelClassWithMethod, "theMethodToCall(20,11)"); 
// With BindingUtils..... 
// bind host: standInHost 
// bind property: "theMethodToCall(20,11)" 

Bien sûr, vous nee pour créer un tel utlity pour aider à soutenir cette fonctionnalité au-delà de la prescription Flex de base. Il semble que beaucoup de telles liaisons Flex (plus avancées) sont habituellement faites au moment de la compilation, mais maintenant vous devez créer du code pour le faire au moment de l'exécution de manière ActionScript multiplateformes sans vous appuyer sur le framework Flex.

Questions connexes