Binding d' une row avec un autre tableau
laurris
Membre
Bonjour,
J' essaie de faire ce qui suit depuis plusieurs semaines sans succes.
Dans l' article sur ce site consacré au NSArrayController, on entre les valeurs du tableau grace à des textField (Titre, Auteur,...).
Ce que j'aimerais faire, c'est d'utiliser un autre tableau à la place de ces textFields. Seule la deuxième colonne contenant les valeurs serait éditable.
J' ai essayé dans tous les sens avec un deuxième NSArrayController bindé au premier ou avec le "transformer" ... j' obtiens des erreurs à chaque fois et je crois que l' objectif dépasse mes capacités.
Est-ce que quelqu' un aurait déjà essayé de faire une telle chose ?
Merci.
Note: C'est pour faire une interface avec une base MySQL
J' essaie de faire ce qui suit depuis plusieurs semaines sans succes.
Dans l' article sur ce site consacré au NSArrayController, on entre les valeurs du tableau grace à des textField (Titre, Auteur,...).
Ce que j'aimerais faire, c'est d'utiliser un autre tableau à la place de ces textFields. Seule la deuxième colonne contenant les valeurs serait éditable.
J' ai essayé dans tous les sens avec un deuxième NSArrayController bindé au premier ou avec le "transformer" ... j' obtiens des erreurs à chaque fois et je crois que l' objectif dépasse mes capacités.
Est-ce que quelqu' un aurait déjà essayé de faire une telle chose ?
Merci.
Note: C'est pour faire une interface avec une base MySQL
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
J'avoue que j'ai du mal à cerner ton problème et le but du deuxième tableau.
Tu peux en dire plus ou faire une capture d'écran stp.
Oui il s' agit bien d' un tableau qui correspond aux keys de la ligne sélectionnée dans le premier tableau.
C' est vrai qu 'on pourrait éditer directement le 1er tableau mais pour des rasisons de design de l'interface je trouve qu'il est plus clair de séparer:
- Le tableau où on visualise les lignes (des champs d'une base MySQL donc)
- Dans un drawer à coté un autre tableau pour éditer ces lignes.
Comme ça j'aurais la possibilité de n' afficher dans le premier tableau que les keys voulues. Par exemple dans le premier tableau je n'aurais qu'une seule colonne avec la key "Titre" et dans le 2eme tableau la posiblité de tout éditer:
Exemple: Le 1er tableau ressemble à ça:
-TITRE-
Machin
Truc
Quand je sélectionne la ligne "Machin", j'ai la possibilité d' éditer toutes les keys qui ne sont pas visibles dans le 1er tableau:
TITRE : | Machin |
Auteur: | John  |
Prix   : | 12 F  |
J' ai déjà essayé avec un NSValueTransformer de transformer une ligne en colonne pour obtenir le 2eme tableau mais les erreurs que j'obtiens sont difficiles à expliquer parce que peu explicites.
Voilà , j'espère que c'est plus clair.
Laurris.
Alors, il faut faire 2 NSArrayController effectivement, un par tableau.
Tu peux les initialiser dans le awakeFromNib 'on the fly", comme nous a appris ClicCool :
Oublie pas de délcarer un outlet sur le premier tableau dans le .h : IBOutlet id tableau1Controller;
Ensuite, il te reste plus qu'à binder les colonnes de tes 2 tableaux en "arrangedObject" avec les clés correspondantes, qui pointent sur tes dictionnaires par exemple.
En revanche, pour transformer les colonnes en lignes (cad mettre les en-tête de colonne sur la droite d'une ligne non ?), je ne sais pas si c'est faisable.
[Fichier joint supprimé par l'administrateur]
Je suis d'accord avec Tiff, le NSForm est une bonne (la meilleure ?) alternative. Tu peux éventuellement gérer à la volée le binding, le nombre d'élements et les intitulés du NSForm.
Sinon, pour gérer avec les bindings une autre tableView pour la saisie il te faut construire un nouvel Array contenant des dictionnaires avec 2 entrées, une pour l'étiquette des champs (1ère collone) l'autre avec la valeur à éditer. Et là les bindings pour la synchro des 2 tableaux est ardue.
Autre solution: utiliser (comme les vieux ;D ) les méthodes datasource pour le 2ème tableau.
Y'a pas moyen, en particulier, d'inverser la présentation Ligne/Colonnes dans les bindings
Je vois pas mieux
J'allais le dire
Pour ce que je veux faire, je crois qu' un 2eme tableau est préférable à une NSForm parce que je voudrais avoir des cellules de différents types dans le tableau: textField, popup, check box ...
Sinon, dans ton exemple osxitan, est-ce que le concept du "binding on the fly" est vraiment nécessaire ou c'est pour pouvoir binder facilement le NSArrayController au Controlleur de l'application ?
Finalement, pour résumer, je me retrouve avec le tableau2Controller qui contient la selection d' un NSMutableArray, c'est à dire un NSMutableDictionary.
Question: si je passe par un NSValueTransformer pour inverser la ligne en colonne est ce que c'est si compliqué ? Il faudrait prendre en entrée un NSMutableDictionary:
{Titre= My way;Auteur= Albert}
Et obtenir un NSMutableArray:
{
{KEY= Titre; VALUE = My way; }
{KEY= Auteur; VALUE = Albert; }
...
}
... et retour pour la transformation inverse.
Ca pourrait le faire ?
PS: J' ai lu la doc du NStransformer mais j'ai presque jamais touché.
C'est excatement ça, et ça évite d'ajouter un contrôleur objet qui fait le pont entre ton controlleur et le controlleur du premier tableau.
En reva,che, pour inverse les lignes, ça va être coton... je pense pas comme ClicCool que ce soit faisable.
C'est même pas que ce soit difficile, c'est absolument impossible sans créer un pseudo-tableau de pseudo-dictionnaires contenant les références aux libellée et contenus.
Il est question d'une plus grande souplesse à l'avenir mais ce n'est pas documenté (même dans la àŸ de Xcode 2.0)
P.S. J'ai pas résisté, j'fais un p'tit tour ici par GPRS, tant pis pour la facture, je suis en manque
Bon j' ai bien saisi que les bindings ne pouvaient pas tout faire. J' ai quand même essayé un truc avec le NSValueTransformer histoire de ne pas abandonner tout de suite. Ce qui est apparemment possible, c'est d'inverser les lignes et de les avoir dans un tableau en lecture seule.
Voilà un projet xcode 1.5 qui fait ça en fichier joint. Pour ce qui est d' éditer les lignes et de renvoyer la valeur vers le 1er tableau, je pressens que c'est pas possible mais j' aimerais bien comprendre quand même pourquoi la methode
- (id)reverseTransformedValue:(id)value
n'est même pas appelée (pas de Log dans la console). Comme ça après j'aurai la conscience tranquille et je pourrais essayer autre chose. En tout cas merci de vous pencher sur mon problème.
A+
[Fichier joint supprimé par l'administrateur]
Je ne peux me me connecter avec mon PB actuellement mais je regarderai volontiers ton code dès que possible.
En attendant, il me semble qu'il y a peu d'avenir à détourner les transformers de leur vocation pour ton problème. Ne serait-ce que parcequ'il te sera difficile (impossible peut-être) d'éditer les valeurs.
La solution est plutôt dans la déclaration d'un pseudo Array (pour les lignes) et un pseudo Dico (pour le colonnes) dont tu implémentera les accesseurs indexés afin que le pseudo array affirme contenir le bon nombre de lignes et renvoie systématiquement un pseudo dico dont tu implémentera également les accesseurs afin qu'il renvoie effectivement le bon objet (pas seulement sa valeur) à éditer (par ses accesseurs) qui alors sera convenablement mis à jour dans le premier tableau.
:crackboom:-
C'est tordu mais ça marche
Et ça me semble moins tordu que le coup des transformers réversibles ou pas ;D
J'espère que ça t'aide
P.S. méfies toi, si la première tableView bindée est triée, les index de lignes ne correspondrons sans doute plus aux index originaux de ton NSMutableArray !!
Oui ça m' aide ... à réfléchir au problème et à essayer d' apprendre un tas de choses que j' ignore encore sur le KVO.
Tu m' as mis sur la piste mais j' ai du mal à passer les vitesses (la pente est forte comme dit l'autre). Donc est ce que tu peux me préciser ce qu' est ce pseudo-array et comment je dois déclarer ses accesseurs indexés. Pour l'instant j' ai bindé programmatiquement les 2 Array controllers à la classe controller de l'application. Le premier a un keyPath qui correspond au NSMutableArray d' origine (pour le 1er tableau) et le second est a un keyPath dont l'accesseur renvoie un Array "retourné" à partir de la selection du 1er Array Controller.
Est-ce que les accesseurs indexés correspondent à countOfArray comme expliqué dans le KVO ?
Sinon, je ne vois pas comment le pseudo-array peut renvoyer un pseudo-dico et pas un autre array inversé. Comme tu vois, je ne suis pas sûr d'avoir bien saisi le concept que tu me propose mais je n' abandonne pasÂ
Voilà ce que j' ai fait pour l'instant:
Me gourre-je ? où vais-je dans le bon sens ?
Merci.
Tu vas bien dans la bonne direction
Mais il me semble que tu te compliques la vie et crées de bien nombreuses variables.
Un détail me frappe dans ton code:
te renvoie un tableau "autoreleasé" non ?
ce serait pas mieux, pour une variable d'instance comme ton tableau, d'utiliser: ?
Pour ce qui est des termes "pseudo array" et "pseudo dictionnaire" je voulais dire des objets quelquonques qui se comportent comme un array ou un dico, c'est a dire implémentant les accesseurs attendus et définis par le KV Coding.
En effet tu as en gros 2 solutions extrèmes possible (ainsi que des tas d'intermédiaires entre les 2)
Soit tu construit à chaque fois à la volée le tableau2 contenant une série de dictionnaires contenant les clefs et les valeurs de chaque clef et valeur de l'objet sélectionné dans le tableau1. je sais la phrase est longue et hardue.
Soit tu fait simplement croire que ces objets existent mais te contentes d'implémenter les accesseurs adéquats.
Le binding sur le pseudo Array n'ira pas vérifier que l'array existe vraiment pourvu qu'il ait une réponse adaptée quand il s'adresse aux accesseurs.
Par exemple si tu bindes sur la model key path "tableau2", il suffit d'implémenter: countOfTableau2 et objectInTableau2AtIndex et insertObject: inTableau2AtIndex: et enfin removeObjectFromTableau2AtIndex +/- replaceObjectInTableau2AtIndex: withObject: pour que ça marche et ce même s'il n'existe pas d'array nommé tableau2.
Tout ça te permet de rester propre et de ne pas multiplier les variables d'instances contenant tes vraies données, celles ci restant sagement dans leur unique tableau. Tes accesseurs de pseudoChoses se chargerons au fur et à mesure de renvoyer sur les bons objets bindés sur la TableView1.
Si c'est pas clair :-\ j'essairais d'être plus concret la prochaine fois
Merci pour tes conseils grace auquels j' ai pu écrire le code qui suit. Encore une fois je bute sur le problème de savoir comment le tableau 1 va être mis à jour avec les valeurs éditées du tableau2. Pour l'instant voilà ce que j' arrive à faire en utilisant la 2eme méthode que tu propose et ça marche plus ou moins. Le moins parce que les valeurs ne sont pas mis à jour instantanément dans le tableau 2 quand on change les valeurs du tableau 1. Il faut sélectionner une ligne du tableau2 pour que les nouvelles valeurs soient pris en compte. Peut - être un mauvais réglage des options dans IB ... ?
[Fichier joint supprimé par l'administrateur]
Je sais pas si tu vas trouver une solution à ton problème mais en tout cas c'est bien que tu persiste. C' est sûr que tu n' as pas l' air d' avancer très vite. peut-être un peu paresseux ?
On sait jamais, ça va peut-être marcher... bon courage.
Signé: Laurris
T'as bien fait de poster pour réactiver le sujet, je l'avais oublié !
Dès que j'ai une minute je rejette un oeil promis
Pour ce qui est de binder le 2eme NSArrayController au 1er, c'est vrai que ça paraitrait plus logique. Je l' ai bindé à self pour utiliser la méthode de ClicCool de "simulation" d'un Array à l'aide de ses accesseurs. Maintenant, si je le fais quand même, il faudrait que je sous-classe le 1er NSArrayController, non ?
Ce que j' ai du mal à concevoir de toute façon, c'est comment les valeurs modifiées du 2eme NSArrayController vont pouvoir être prises en compte par le 1er.
C'est là que ça ( je ) bloque, je pense.
En tout cas je n' ai pas avancé depuis le projet posté en attachement et qui marche dans un sens seulement (message précédent).
A+.