Tutoriel de David Shaffer/Call/Answer: Afficher un autre composant

From OFSET Wiki

Jump to: navigation, search

Traduction de : Call/Answer


Seaside



Contents

[edit] Notions de base

Comment changer la valeur d'un composant que l'on est en train d'afficher ? Nous avons deux composants: HelloWorldComponent et PersonalInformationView qui sont des composants racines de deux applications (il peuvent être accèder directement). Normalement, une application ne possède qu'un seul composant racine correspondant au point d'entrée, et les autres composants sont affichés en fonction des différentes actions de l'utilisateur. Alors, comment peut-on créer un lien dans le premier composant afin d'y afficher le second ? Pour cela nous avons recours à la méthode call: (le composant HelloWorldComponent est donc modifié en conséquence) :

renderContentOn: html
  html heading: 'Hello world' level: 1.
  html anchorWithAction: [self editPersonalInformation] text: 'Edit personal information'
editPersonalInformation
  self call: PersonalInformationView new.

Ensuite nous modifions le composant PersonalInformationView de manière à ce que lorsque les utilisateurs appuie sur save, ils soient redirigés vers le composant appelant (HelloWorldComponent).

save
  self answer

Notez que la méthode editPersonalInformationView crée une nouvelle instance de PersonalInformationView puis l'appelle via call:. Lorsque vous appelez le composant, vous lui donner le contrôle. Quand ce composant a terminé son traitement (dans le cas présent, lorsque l'utilisateur appuie sur "save"), il doit exécuter la méthode answer pour redonner le contrôle au composant qui l'a appelé précédemment. Essayez maintenant l'application, et cliquez sur le lien. Remplissez le formulaire et appuyez sur "save". Notez que vous êtes revenus sur le composant "hello world". En résumé, vous appelez un composant et quand ce composant a terminé son traitement, il rend le contrôle de l'affichage au composant qui l'a appelé. Les méthodes call et answer d'un composant Seaside sont équivalentes respectivement au fait d'ouvrir et de fermer une boîte de dialogue modale.

[edit] Séquencement

Comme je l'ai indiqué précédemment, l'appel d'un composant est une interaction modale. C'est-à-dire que la méthode call: ne retourne pas de résultat tant que le composant qu'elle appelle n'exécute pas la méthode answer. Ce mécanisme nous permet de réaliser des choses comme celle-ci ( dans HelloWorldComponent ) :

editPersonalInformation
  | v |
  v := PersonalInformationView new.
  self call: v.
  self inform: 'Hello ' , v name

Ici nous appelons la vue. Une fois que la vue a répondu, nous affichons le message. Maintenant, voici quelque chose pour vous triturer les méninges... Que se passerait-il si l'utilisateur remplissait le formulaire, appuyait sur save, puis appuyait sur le bouton précédent, changeait les valeurs du formulaire et sauvait à nouveau ? Après la première sauvegarde la méthode ci-dessus est en train d'appeler inform: mais lorsque l'utilisateur appuie sur précédent, la méthode revient en arrière au niveau de call: avec en paramètres le composant PersonalInformationView. Concrètement, seaside capture l'état de l'exécution de votre méthode, ainsi, il peut "revenir en arrière" en réponse au bouton précédent. Nous verrons plus en détails ce mécanisme un peu plus tard mais pour l'instant essayez de l'implémenter et assurez vous que tout fonctionne comme vous le voulez.

[edit] Retourner une valeur au composant appelant

Il y a une version de la méthode answer qui prend un argument. Cette version retourne une valeur au composant appelant. Cette méthode est fréquemment utilisée pour retourner un booléen pour indiqué si l'utilisateur à annuler ou confirmer une operation. Nous n'avons pas de bouton cancel dans PersonalInformationView. Ajoutons-en un et retournons une valeur de manière appropriée. Premièrement ajoutez la ligne suivante à la fin du formulaire :

html spanClass: 'button'
          with: [html submitButtonWithAction: [self cancel]
                                        text: 'Cancel']

Et faites les changement suivant :

save
  self answer: true

Ajoutez la méthode :

cancel
  self answer: false

Maintenant nous devons modifier HelloWorldComponent pour utiliser la valeur retournée :

editPersonalInformation
  | v |
  v := PersonalInformationView new.
  (self call: v) ifFalse: [^nil].
  self inform: 'Hello ' , v name

[edit] Exercices

  • Quelque chose avec call/answer

[edit] Un oeil sur les boîtes de dialogues intégrées à Seaside

Il est temps de jeter un oeil sur le code source de la méthode inform:. Voici celui de WAComponent (n'appuyer pas sur "entrer" !!!!) :

inform: aString
  self call: (WAFormDialog new addMessage: aString)

inform: exécute call: pour ouvrir une WAFormDialog. Quelles autres méthodes ressemblant à celle-ci peut-on trouver ? En explorant WAComponent on trouve :

  • confirm: -- Affiche un message et des boutons "Yes" et "No". Retourne vrai si l'utilisateur appuie sur "Yes", faux autrement.
  • request:, request:default:, request:label:, request:label:default: -- affiche un message, un label optionnel et un zone de saisie. La chaîne entrée dans la zone de saisie est retournée. Si l'argument default: est spécifié, il est utilisé pour initialiser le contenu de la zone de saisie.

Regardez ces boîtes de dialogues puis créez les votre.

We look at these dialogs and creating your own in Standard dialogs.

[edit] Exercices

  • Quelque chose avec request: puisque nous en aurons besoin plus tard

[edit] Ne pas utiliser call: dans renderContentOn:

Une des erreurs les plus communes pour les utilisateurs novices de Seaside est d'appeler un composant via la méthode call: depuis la méthode de rendu d'autres composants, renderContentOn:. La méthode de rendu n'est utilisée que pour cela, le rendu. Elle devrait afficher uniquement l'état courant du composant tel qu'il est. C'est le travail des callbacks de changer l'état, d'appeler d'autres composants, etc.

Il n'y a pas de raison pour un utilisateur de Seaside d'invoquer la méthode call: pendant un rendu. Si vous voulez afficher un autre composant dans un autre lisez le chapitre Embedding components


[edit] Notes

  • La notion de "composant racine" est un point sur lequel je veux revenir. Seaside gère une liste d'"Applications". Chacune d'entre elles possède une URL ainsi qu'un composant racine. Lorsque nous envoyons le message registerAsApplication: à une classe d'un composant, celle-ci s'enregistre comme composant racine de la nouvelle application. Vous n'avez pas besoin d'enregistrer tous vos composants comme racines de vos applications. Le fait que PersonalInformationView était le composant racine de l'application n'a pas d'effet sur l'exemple ci-dessus. En fait, nous pouvons supprimer cette application en évaluant :
WADispatcher default entryPoints removeKey: 'personal'

mais notre méthode call: marchera toujours. call: affiche un composant, pas une application différente. Gardez bien à l'esprit cette distinction entre un composant et une application.

Personal tools