2009-08-31 4 views
0

J'essaie de composer l'une des parties de l'interface utilisateur d'une application AIR que je développe dans Flex. Dans cet exemple, je souhaite afficher les informations de fichier sur une seule ligne (avec une icône, du texte/lien et la taille).Utilisation d'un composant MXML composite à partir d'ActionScript

Mon code ressemble à ceci (le composant est appelé FichierAffiche):

<?xml version="1.0" encoding="utf-8"?> 
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Script> 
     <![CDATA[ 
      public function set iconType(source:String):void { 
       this.ficon.source = source; 
      } 

      public function set fileName(name:String):void { 
       this.fname.htmlText = name; 
      } 

      public function set fileSize(size:String):void { 
       this.fsize.text = size; 
      } 
     ]]> 
    </mx:Script> 
    <mx:Image id="ficon" /> 
    <mx:Label id="fname" left="20" right="30" text="Filename" /> 
    <mx:Label id="fsize" right="0" text="0 K" /> 
</mx:Canvas> 

Lorsque j'utilise ce composant dans ma principale application, l'actionscript ressemble:

for each (var file:XML in result.files) { 
    var fd:FileDisplay = new FileDisplay(); 
    fd.fileName = '<a href="blah">'+file.name+'</a>'; 
    fd.iconType = getFileTypeIcon(file.name); 
    fd.fileSize = getFileSizeString(file.size); 

    this.file_list.addChild(fd); 
} 

Toutefois, lorsque Je fais cela, j'obtiens une erreur: Erreur # 1009: Impossible d'accéder à une propriété ou méthode d'une référence d'objet null. Cela est dû au fait que les composants enfants de FileDisplay sont null (ou du moins, ils apparaissent dans le débogueur).

Est-ce que quelqu'un sait s'il y a un moyen de contourner cela? Suis-je censé attendre des événements indiquant que les composants enfants ont été créés? Y at-il un modèle plus commun qui résout ce problème? Pour l'instant je peux faire manuellement tout dans ActionScript dans mon application principale (créer un Canvas et y ajouter des enfants) mais j'apprécierais toute idée sur la façon de séparer le code plus proprement.

Répondre

3

Bindable à la rescousse:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> 
    <mx:Script> 
     <![CDATA[ 
       [Bindable] 
       public var iconType:String; 
       [Bindable] 
       public var fileName:String = "Filename"; 
       [Bindable] 
       public var fileSize:String = "0 K"; 
     ]]> 
    </mx:Script> 
    <mx:Image id="ficon" source="{iconType}"/> 
    <mx:Label id="fname" left="20" right="30" text="{fileName}" /> 
    <mx:Label id="fsize" right="0" text="{fileSize}" /> 
</mx:Canvas> 

les valeurs seront automatiquement mises à jour lorsque les composants sont créés.

1

Les sous-composants n'ont pas encore été chargés.

Lisez ceci: http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_2.html#203434. Puis, quand comme moi, vous ne le comprenez pas (et ce n'est pas fiable), écoutez le FlexEvent.CREATION_COMPLETE dans FileDisplay, et appliquez-y les propriétés de votre composant enfant.

Ou mieux encore, créez les trois enfants par programmation dans la fonction "createChildren" et appliquez les paramètres ici.

Ces deux méthodes supposent que vous définissez filename, icontype et filesize en tant que membres locaux avant de les appliquer aux composants enfants, ce que vous devez faire indépendamment.

+0

Merci pour la perspicacité. Les docs sur l'utilisation de composants personnalisés "avancés" sont assez déroutants. J'ai l'impression que mon cas n'est pas si rare qu'ils devraient probablement avoir plus d'exemples comme ça. –

1

Quel est le composant parent qui contient le composant FileDisplay? Si vous êtes sûr que l'erreur provient du fait que les composants enfants de FileDisplay ne sont pas instanciés, vous pouvez examiner l'attribut creationPolicy et vous assurer qu'il est défini sur ContainerCreationPolicy.ALL sur ce composant parent.

= Ryan

+0

Peu importe. Les enfants de FileDisplay n'ont pas le temps d'être créés entre l'appel «new FileDisplay()» et l'affectation des propriétés. – Glenn

0

Outre la définition de la propriété CreationPolicy, vous devez ajouter DisplayObject à la scène via addChild. Les enfants de FileDisplay ne sont pas créés jusqu'à ce que vous ajoutiez il est ajouté à la scène. Alors faites:

for each (var file:XML in result.files) { 
    var fd:FileDisplay = new FileDisplay(); 
    this.file_list.addChild(fd); 

    fd.fileName = '<a href="blah">'+file.name+'</a>'; 
    fd.iconType = getFileTypeIcon(file.name); 
    fd.fileSize = getFileSizeString(file.size);  
} 
Questions connexes