Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > Flash/Flex > Flex
Flex Forum d'entraide sur la programmation Adobe Flex : applications Internet riches (RIA)
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/11/2011, 11h39   #1
Tan
Membre habitué
 
Inscription : janvier 2004
Messages : 168
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 168
Points : 125
Points : 125
Envoyer un message via MSN à Tan
Par défaut datagrid éditable créée dynamiquement

Bonjour,

Je cherche à créer dynamiquement des DataDrid en fonction d'une source de données (pour l'instant XML), et j'ai une erreur à l'utilisation (voir à la fin de ce post).
Code :
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
31
32
33
34
35
36
37
38
39
40
41
 
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   contentCreationComplete="init()">
 
	<fx:Declarations>
		<fx:XML id="xmlData" source="xml/xmlData.xml"/>
		<s:ArrayList id="columns">
			<s:GridColumn dataField="@nom" editable="true"/>
		</s:ArrayList>
	</fx:Declarations>
 
	<fx:Script>
		<![CDATA[
			import mx.collections.XMLListCollection;
			import spark.components.DataGrid;
 
			private function init():void {
				var elt:XMLList = xmlData.element.(@nom == "Test1");
				// Pour tous les regroupements
				for each(var grp:XML in elt.regroupements.regroupement) {				
					// Ajoute d'une dataGrid au panel (contenant les items du groupe)
					var dataGrid:DataGrid = new DataGrid();
					dataGrid.dataProvider=new XMLListCollection(grp.item);
					dataGrid.columns=columns;
					dataGrid.editable=true;
					panel.addElement(dataGrid);
				}
			}
		]]>
	</fx:Script>
 
 
	<s:Panel id="panel">
		<s:layout>
			<s:TileLayout requestedColumnCount="3"/>
		</s:layout>
	</s:Panel>
</s:Application>
Voici le fichier XML:
Code :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<provider>
	<element nom="Test1">
		<regroupements>
			<regroupement nom="grp1">
				<item nom="Grp1Item1"/>
				<item nom="Grp1Item2"/>
				<item nom="Grp1Item3"/>
			</regroupement>
			<regroupement nom="grp2">
				<item nom="Grp2Item1"/>
				<item nom="Grp2Item2"/>
				<item nom="Grp2Item3"/>
				<item nom="Grp2Item4"/>
				<item nom="Grp2Item5"/>
			</regroupement>
			<regroupement nom="grp3">
				<item nom="Grp3Item1"/>
				<item nom="Grp3Item2"/>
				<item nom="Grp3Item3"/>
			</regroupement>
			<regroupement nom="grp4">
				<item nom="Grp4Item1"/>
				<item nom="Grp4Item2"/>
			</regroupement>
		</regroupements>
	</element>
	<element nom="Test2">
		<regroupements>
			<regroupement nom="grp1">
				<item nom="Grp1Item1"/>
				<item nom="Grp1Item2"/>
			</regroupement>
			<regroupement nom="grp2">
				<item nom="Grp2Item1"/>
				<item nom="Grp2Item2"/>
				<item nom="Grp2Item3"/>
				<item nom="Grp2Item4"/>
			</regroupement>
			<regroupement nom="grp3">
				<item nom="Grp3Item1"/>
				<item nom="Grp3Item2"/>
			</regroupement>
			<regroupement nom="grp4">
				<item nom="Grp4Item1"/>
				<item nom="Grp4Item2"/>
				<item nom="Grp4Item3"/>
				<item nom="Grp4Item4"/>
				<item nom="Grp4Item5"/>
			</regroupement>
		</regroupements>
	</element>
</provider>
Ici, à partir d'un fichier XML, je crée dynamiquement plusieurs dataGrid. Dans ce cas, 4 dataGrid.

Par contre, lorsque j'essaie d'éditer les deux premières lignes de n'importe quelle dataGrid, ça fonctionne, dès que j'essaie de modifier une ligne d'indice supérieure, J'ai une erreur:
Citation:
TypeError: Error #1009: Il est impossible d'accéder à la propriété ou à la méthode d'une référence d'objet nul.
at spark.components.gridClasses:efaultGridItemEditor/prepare()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DefaultGridItemEditor.mxml:114]
at spark.components.gridClasses:ataGridEditor/http://www.adobe.com/2006/flex/mx/internal::createItemEditor()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DataGridEditor.as:623]
at spark.components.gridClasses:ataGridEditor/setEditedItemPosition()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DataGridEditor.as:286]
at spark.components.gridClasses:ataGridEditor/dataGrid_gridItemEditorSessionStartingHandler()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DataGridEditor.as:1204]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:13128]
at spark.components.gridClasses:ataGridEditor/startItemEditorSession()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DataGridEditor.as:798]
at spark.components:ataGrid/startItemEditorSession()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\DataGrid.as:3803]
at spark.components.gridClasses:ataGridEditor/grid_gridMouseUpHandler()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\gridClasses\DataGridEditor.as:1379]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:13128]
at spark.components::Grid/dispatchGridEvent()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\Grid.as:4038]
at spark.components::Grid/grid_mouseDownDragUpHandler()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\Grid.as:3883]
at Function/<anonymous>()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\utils\MouseEventUtil.as:96]
Tout ce comporte comme-ci une fois chargé, le data provider était celui de la dernière liste.

Donc, pour que cela fonctionne, il faut que le dernier dataGrid soit celui qui a le plus grand nombre de lignes. Ce qui n'est pas acceptable.

Je ne comprends pas, normalement chaque instance de datagrid doit avoir son propre dataprovider.

Avez-vous ne serait-ce qu'une piste?
Tan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 12h26   #2
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 279
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 279
Points : 2 327
Points : 2 327
Salut,

fais ceci et ca marchera

Code :
1
2
3
4
5
6
7
8
9
10
11
 
private function init():void {
 
	for each(var grp:XML in xmlData.element.(@nom == "Test1")..regroupement){
		var dataGrid:DataGrid = new DataGrid();
		dataGrid.editable = true;
		dataGrid.dataProvider = new XMLListCollection(XMLList(grp.item));
		panel.addElement(dataGrid);
	}
 
}
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 12h57   #3
Tan
Membre habitué
 
Inscription : janvier 2004
Messages : 168
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 168
Points : 125
Points : 125
Envoyer un message via MSN à Tan
D'abord merci pour ta réponse, j'ai appris en passant la syntaxe .. de l'e4x que je n'avais jamais essayé (proche de la syntaxe xpath pour le coup). Je suis tout nouveau en FLEX et je découvre un peu.

Ta solution fonctionne, et je vois donc que mon problème viens de l'utilisation de columns.

As-tu une explication sur la cause du problème car j'ai d'autres dysfonctionnements sur les datagrid alimentés par XML, et cela m'aiderait peut-être à les résoudre?

Si je ne dois pas utiliser columns, comment devrais-je faire si j'ai besoin de définir explicitement certaines colonnes:
- Titre d'entête
- éditable ou pas
- ...
Tan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 13h44   #4
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 279
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 279
Points : 2 327
Points : 2 327
A vrai dire je n'utilise jamais ta solution à savoir définir les columns dans les métadonnées Declarations. Je pars du principe que si tu les déclares dans ce tag, elles ne sont pas dynamiques et peuvent par conséquent être "ecrites en dur" en mxml.
Sinon si elles sont dynamiques j'utilise as3 et une boucle par exemple.
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 14h20   #5
Tan
Membre habitué
 
Inscription : janvier 2004
Messages : 168
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 168
Points : 125
Points : 125
Envoyer un message via MSN à Tan
Effectivement, en déclarant les colonnes en AS3 dans la boucle cela fonctionne.
Par contre, quand je déclare en AS3 hors de la boucle, j'ai l'erreur.

Avec l'AS3 dans la boucle ça fonctionne:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private function init():void {
	// Pour tous les regroupements
	for each(var grp:XML in xmlData.element.(@nom == "Test1")..regroupement) {				
		// Ajoute d'une dataGrid au panel (contenant les items du groupe)
		var dataGrid:DataGrid = new DataGrid();
		dataGrid.dataProvider=new XMLListCollection(XMLList(grp.item));
 
		// définition des colonnes
		var columns:ArrayList = new ArrayList();
		var columnItem:GridColumn = new GridColumn();
		columnItem.dataField="@nom";
		columns.addItem(columnItem);
		dataGrid.columns=columns;
 
		dataGrid.editable=true;
		panel.addElement(dataGrid);
	}
}
Avec l'AS3 hors de la boucle ça fonctionne:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private function init():void {
	// définition des colonnes
	var columns:ArrayList = new ArrayList();
	var columnItem:GridColumn = new GridColumn();
	columnItem.dataField="@nom";
	columns.addItem(columnItem);			
 
	// Pour tous les regroupements
	for each(var grp:XML in xmlData.element.(@nom == "Test1")..regroupement) {				
		// Ajoute d'une dataGrid au panel (contenant les items du groupe)
		var dataGrid:DataGrid = new DataGrid();
		dataGrid.dataProvider=new XMLListCollection(XMLList(grp.item));
 
		dataGrid.columns=columns;	
		dataGrid.editable=true;
		panel.addElement(dataGrid);
	}
}
Le problème se situe donc dans l'utilisation d'une variable commune pour "columns" à toutes les instances de DataGrid.

Je trouve ce comportement très étrange, et je n'ai pas d'explication.
Je compte mettre "Résolu" à ce post, mais je voulais d'abord savoir si tu avais une explication sur cette différence de comportement.
Tan est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 15h12   #6
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 279
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 279
Points : 2 327
Points : 2 327
C'est probablement du au fait que lorsque tu initialises columns hors de la boucle cette variable est initialisée 1 seule fois. Donc tu as X datagrids avec une seule référence de columns. Dès lors, a chaque demande d’édition d'un champs d'index > 1, le système essaie d'éditer dans le dataprovider de chaque datagrid possédant cette instance de columns, la valeur. Or, dans certains datagrids, cela sort en erreur car tous tes dataprovider non pas tous la même taille.

Quand bien même ils auraient tous la même taille, tu risquerais d'avoir des résultats non voulus voir incompréhensibles.

Il te faut donc un référence distincte de columns par datagrid.
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/11/2011, 15h23   #7
Tan
Membre habitué
 
Inscription : janvier 2004
Messages : 168
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 168
Points : 125
Points : 125
Envoyer un message via MSN à Tan
Ok merci, j'essaierai de garder ça en tête pour éviter ce genre d'erreur, même si je ne trouve pas ça très naturel.

En tout cas merci, car je pense que j'aurai peiné à trouver, j'aurai plus chercher une cause sr le dataprovider.
Tan est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h35.


 
 
 
 
Partenaires

Hébergement Web