IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Flex Discussion :

Datagrid, Recyclage et ItemRenderer [Flex4]


Sujet :

Flex

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 43
    Par défaut Datagrid, Recyclage et ItemRenderer
    Bonjour.

    Je crois que cette discussion revient souvent sur le net, mais je n'ai pu trouver de réponse satisfaisante ...

    Dans un datagrid, j'ai une colonne dont l'ItemRenderer varie en fonction d'un champ de la donnée à afficher. Ces renderer peuvent contenir un ou plusieurs contrôles différents.

    Mon tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <mx:DataGrid id="dg" dataProvider="{var}" variableRowHeight="true" >
    		<mx:columns>
    			<mx:DataGridColumn dataField="a" />
    			<mx:DataGridColumn dataField="b" />
    			<mx:DataGridColumn dataField="c" itemRenderer="composants.Rendu"/>
    		</mx:columns>
    	</mx:DataGrid>
    Mon ItemRenderer qui contient un VGroup auquel j'ajoute à l'initialisation un composant particulier en fonction du type de la data à afficher:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    private function init():void
    {
         switch(data.c)
        {
            case "Type1" :
    		vgroup.addElement(new renduPanelType1());
    		break;
    	case "Type2" :
    		vgroup.addElement(new renduPanelType2());
    		break;
         }
    }
    Jusque là, tout va bien, j'ai bien un tableau qui s'affiche avec mes renderers différents.

    Le problème est le suivant, tous les Renderers sont bouleversés lorsque l'utilisateur utilise l'ascenseur vertical du tableau.

    Est il possible de régénérer les ItemsRenderers lors du scroll ?
    Est il possible d'empêcher le recyclage des ItemRenderers ?

    Merci d'avance ...

  2. #2
    Membre émérite
    Homme Profil pro
    Consultant Angular / Java J2EE
    Inscrit en
    Novembre 2008
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant Angular / Java J2EE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 545
    Par défaut
    Salut,

    plutôt que de mettre ce code dans la fonction init(), essaye plutôt de le mettre dans la fonction data():

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     override public function set data(value:Object):void
    {				
    	super.data = value;
            switch(data.c)
            {
                case "Type1" :
    	        vgroup.addElement(new renduPanelType1());
    		break;
    	    case "Type2" :
    		vgroup.addElement(new renduPanelType2());
    		break;
            }
    }

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 124
    Par défaut
    Une autre solution (plus efficace ?) est de créer systèmatiquement le renduPanelType1 et de jouer simplement sur ses attributs visible et includeInLayout dans la methode updateDisplayList en fonction de ton data.c.

    Krazymins,
    En faisant tel que tu le proposes, j'ai déjà rencontré des problèmes de nullPointer avec l'objet vgroup (dans l'exemple ci-présent). Sans trop savoir pourquoi.
    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.controls.listClasses.IListItemRenderer">
      <mx:Script>
        <![CDATA[
          override public function set data( value:Object ) : void {
            super.data = value;
            check.selected = ListBase(owner).isItemSelected(data);
            if (data is Uf)
              txt.text = data.code;
            if (data is Ressource)
              txt.text = data.libelleCourt;
            if (data is NatureActe)
              txt.text = data.mnemonique;
          }
          
          override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            check.selected = ListBase(owner).isItemSelected(data);
            if (data is Uf)
              txt.text = data.code;
            if (data is Ressource)
              txt.text = data.libelleCourt;
            if (data is NatureActe)
              txt.text = data.mnemonique;
          }
        ]]>
      </mx:Script>
      <mx:CheckBox id="check" mouseEnabled="false"/>
      <mx:Label id="txt" toolTip="{data.libelleComplet}"/>
    </mx:HBox>
    Le code, placé en rouge, me donne un nullPointer sur txt.
    Le code en vert, lui, fonctionne bien.

  4. #4
    Membre émérite
    Homme Profil pro
    Consultant Angular / Java J2EE
    Inscrit en
    Novembre 2008
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Consultant Angular / Java J2EE
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 545
    Par défaut
    Après réflexion, lorsque je fais un override sur la fonction set data(), c'est pour choisir un state d'affichage. Dans le cas où l'on a besoin d'un itemRenderer générique, par exemple, afficher soit une image, soit une checkbox.
    Donc les states s'opèrent sur des <mx:Addchild...>.
    Ainsi dans mon set data(), j'ai plutôt des lignes du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.currentState = ....;
    A priori, la fonction set data() doit être appelée avant la création des composants. D'où le message d'erreur dans ce cas.

    Effectivement, overrider la fonction updateDisplayList() me semble plus judicieux ici, car elle ne s'applique qu'à l'affichage.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 124
    Par défaut
    Citation Envoyé par Krazymins Voir le message
    A priori, la fonction set data() doit être appelée avant la création des composants. D'où le message d'erreur dans ce cas.
    C'est ce que j'en déduis aussi mais cela me semble un peu étrange comme comportement et surtout pas systématique (et donc d'autant plus étrange ).
    A croire que le set data et le createChildren sont exécutés en concurrence ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 43
    Par défaut
    Citation Envoyé par clemoigno Voir le message
    Une autre solution (plus efficace ?) est de créer systèmatiquement le renduPanelType1 et de jouer simplement sur ses attributs visible et includeInLayout dans la methode updateDisplayList en fonction de ton data.c.
    Je ne vois pas en quoi cette solution permettrait de corriger l'erreur d'affichage (problème de scroll ) ? Peux tu m'en dire plus ?

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 124
    Par défaut
    Ta fonction init() n'est appelée qu'à la création de ton renderer.
    Or, le principe des renderers, c'est d'agir plus ou moins comme un pool d'objets d'affichage qui va être réutiliser en injectant des data nouvelles quand nécessaire.

    En gros, si t'as une liste de 100 éléments dont 5 sont affichés, Flex va te créer 5 instance de renderers qu'il va recycler avec les data qui vont bien au moment ou tu vas scroller.
    Or, ta méthode init() aura été executée avec une autre data à l'instanciation du renderer, et elle ne sera pas réexecuté avec ta nouvelle data. La méthode updateDisplayList, est elle rappelée systématiquement.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 43
    Par défaut
    En effet, cela marche beaucoup mieux de passer par cette fonction (et non la fonction init).

    Il me reste maintenant à rendre le code plus élégant, et faire en sorte que l'espace la hauteur de la ligne corresponde à la hauteur des contrôles affichés.

    Merci beaucoup pour vos réponses

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 19/06/2009, 15h28
  2. datagrid editable Itemrenderer avec checkbox
    Par Cdic83 dans le forum MXML
    Réponses: 3
    Dernier message: 18/05/2009, 22h00
  3. Flex, DataGrid et ItemRenderer
    Par zwan.bourg dans le forum Flex
    Réponses: 9
    Dernier message: 11/05/2009, 14h35
  4. Bug DataGrid avec ItemRenderer
    Par djmalo dans le forum Flex
    Réponses: 4
    Dernier message: 03/03/2009, 16h17
  5. Réponses: 0
    Dernier message: 20/11/2008, 21h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo