xulfr.org

7.9 Broadcasters et Observateurs

Écrit par Neil Deakin. Traduit par BrainBooster (20/07/2004).
Page originale : http://www.xulplanet.com/tutorials/xultu/broadob.html xulplanet.com

Il y a des moments où vous voulez que plusieurs éléments répondent à des événements ou changent d'état aisément. Pour cela, nous pouvons utiliser les «broadcasters» (diffuseurs).

Commandes de transmission de paramètres

Nous avons déjà vu que les éléments tels que les boutons peuvent être ancrés à des commandes. De plus si vous placez l'attribut disabled sur l'élément command, chacun des éléments ancrés sur celui-ci seront eux aussi désactivés automatiquement. Ceci peut être une façon utile de diminuer la taille du code nécessaire. Cette technique fonctionne aussi pour les autres attributs. Par exemple, si vous placez un attribut label sur un élément command, chaque bouton attaché à la commande partagera ce libellé.

Exemple 7.9.1 : Source Voir

<command id="ma_commande" label="Ouvrir"/>

<button command="ma_commande"/>
<checkbox label="Ouvrir une nouvelle fenêtre" command="ma_commande"/>

Dans cet exemple le bouton n'a pas l'attribut label, néanmoins il est attaché à une commande qui en possède un. Le bouton va donc le partager avec la commande. La case à cocher a déjà un libellé, néanmoins, il va être surchargé par celui de la commande. Le résultat est que le bouton et la case à cocher auront le même libellé Ouvrir.

S'il vous arrivait de changer l'attribut label de la commande, les libellés du bouton et de la case à cocher changeraient eux aussi. Nous avons vu quelque chose comme ça dans une section précédente où l'attribut disabled était défini puis propagé aux autres éléments.

Cette transmission d'attribut est relativement utile pour plusieurs raisons. Par exemple, disons que nous voulons désactiver l'action "Page précédente" (Back) dans un navigateur. Nous aurions besoin de désactiver cette action dans le menu, dans la barre des taches, le raccourci clavier (Alt+Left par ex.) et chaque commande "Page précédente" des menus déroulants. Bien que nous pourrions écrire un script pour faire ceci, ce n'est pas très simple. Ça a aussi le désavantage d'avoir à prévoir tous les endroits où pourraient se trouver les boutons "Page précédente". Si quelqu'un a ajouté un nouveau bouton "Page précédente" en utilisant une extension, il ne serait pas pris en compte. Il est plus pratique de désactiver simplement l'action "Page précédente" et d'avoir tous les éléments utilisant cette action se désactiver eux même. Nous pouvons utiliser la transmission d'attribut des commandes pour accomplir cela.

Broadcasters

Il y a un élément similaire appelé broadcaster. Les Broadcasters supportent la transmission d'attributs de la même manière que les commandes. Ils fonctionnent de la même manière excepté qu'une commande est utilisée pour les actions, alors qu'un broadcaster est utilisé pour contenir l'information d'un état. Par exemple, un élément command serait utilisée pour une action comme "Retour", "Couper" ou "Supprimer". Un broadcaster serait utilisé pour contenir, par exemple, un drapeau indiquant si l'utilisateur est en ligne ou non. Dans le premier cas, les éléments du menu et de la barre des tâches nécessiteraient d'être désactivé lorsqu'il n'y a pas de page de retour, ou aucun texte à couper, à effacer. Dans le second cas, plusieurs éléments de l'interface auraient besoin d'être mis à jour lorsque l'utilisateur passerait du mode en ligne au mode hors ligne.

Le broadcaster le plus simple est défini ci-dessous. Vous devriez toujours utiliser un attribut id afin qu'il puisse être référencé à partir d'autres éléments.

<broadcasterset>
  <broadcaster id="isOffline" label="Hors ligne"/>
</broadcasterset>

Tous les éléments qui observent le broadcaster seront modifiés automatiquement chaque fois que l'attribut label du broadcaster change. Ces éléments auront comme résultat un nouveau libellé. Tout comme d'autres éléments non affichés, l'élément broadcasterset est un conteneur pour les broadcasters. Vous devez déclarer tous vos broadcasters dans un élément broadcasterset afin de les réunir.

Les éléments qui observent le broadcaster sont appelés observateurs car ils observent l'état du broadcaster. Pour qu'un élément devienne un observateur, ajoutez lui un attribut observes. Cela revient au même qu'utiliser l'attribut command lorsqu'on attache un élément à un élément command. Par exemple, pour faire d'un bouton un observateur du broadcaster ci-dessus :

<button id="offline_button" observes="isOffline"/>

L'attribut observes a été placé sur le bouton et sa valeur a été affectée à la valeur de l'id du broadcaster à observer. Ici le bouton va observer le broadcaster qui a l'id isOffline, qui est définie un peu plus haut dans le code. Si la valeur de l'attribut label sur le broadcaster change, les observateurs vont mettre à jour leur valeur de l'attribut label à leur tour.

Nous pourrions continuer avec des éléments suppémentaires. Autant d'éléments que vous voulez peuvent observer un simple broadcaster. Vous pouvez aussi n'en avoir qu'un seul mais cela ne servirait pas à grand chose puisque la raison principale d'utiliser les broadcasters est d'avoir des attributs transmis à de multiples endroits. Vous ne devriez utiliser les broadcasters que lorsque vous avez besoin que plusieurs éléments aient à observer un attribut. Ci-dessous quelques observateurs supplémentaires sont décrits :

<broadcaster id="offline_command" label="Hors ligne" accesskey="f"/>

<keyset>
  <key id="goonline_key" observes="offline_command" modifiers="accel" key="O"/>
<keyset>
<menuitem id="offline_menuitem" observes="offline_command"/>
<toolbarbutton id="offline_toolbarbutton" observes="offline_command"/>

Dans cet exemple, à la fois le label et l'accesskey seront transmis par le broadcaster au raccourci clavier, à l'item de menu et au bouton de la barre d'outil. Le raccourci clavier n'utilisera aucun des attributs reçus, mais il sera désactivé lorsque le boradcaster le sera.

Vous pouvez utiliser un broadcaster pour observer n'importe quel attribut désiré. Les observateurs récupèreront toutes les valeurs de chaque attribut via les broadcasters si jamais ils changent. Si jamais la valeur d'un seul attribut change, les observateurs seront avisés et mettront à jour leurs valeurs afin de correspondre. Les attributs des observateurs que le broadcaster n'a pas lui même ne sont pas modifiés. Les seuls attributs qui ne sont pas modifiés sont les attributs id et persist, ces attributs ne sont jamais partagés. Vous pouvez aussi utiliser vos propres attributs si vous désirez.

Les broadcaster ne sont pas fréquemment utilisés, car les commandes peuvent en général convenir à la majorité des usages. Une chose à préciser est qu'il n'y a pas vraiment de différence entre l'élément command et l'élément broadcaster. Ils font tous les deux la même chose. La différence est plus sémantique. Utilisez les commandes pour les actions et utilisez les broadcasters pour les états. En fait, chaque élément peut agir comme un broadcaster, tant que vous l'observez en utilisant l'attribut observes.

l'élément Observes

Il y a un moyen d'être plus spécifique quant à l'attribut du broadcaster à observer. Cela implique un élément observes. Tout comme son attribut l'indique, il vous permet d'indiquer à un élément qu'il est un observateur. L'élément observes doit être placé en tant qu'enfant de l'élément qui doit être l'observateur. Un exemple est décrit plus bas :

Exemple 7.9.2 : Source Voir

<broadcasterset>
  <broadcaster id="isOffline" label="Hors ligne" accesskey="f"/>
</broadcasterset>

<button id="offline_button">
  <observes element="isOffline" attribute="label"/>
</button>

Deux attributs ont été ajoutés à l'élément observes. Le premier, element, spécifie l'identifiant du broadcaster à observer. Le second, attribute, spécifie l'attribut à observer. Le résultat est que le bouton recevra son libellé du broadcaster, et quand l'attribut label sera modifié, le libellé du bouton sera changé. L'élément observes ne change pas contrairement à l'élément qui le contient, qui est dans ce cas un button. Notez que l'attribut accesskey n'est pas transmis au bouton, puisque il n'est pas observé. Si vous voulez que ce soit le cas, un autre élément observes devra être ajouté. Si vous n'utilisez aucun élément observes, et qu'à la place vous utilisez l'attribut observes directement sur le bouton, tous les attributs seront observés.

Il y a un gestionnaire d'évenement supplémentaire que nous pouvons placer sur l'element observes qui est onbroadcast. L'évenement est appelé même si l'observateur détecte un changement dans l'attribut du broadcaster qu'il observe. Un exemple est décrit ci-dessous :

Exemple 7.9.3 : Source Voir

<broadcasterset>
  <broadcaster id="colorChanger" style="color: black"/>
</broadcasterset>

<button label="Test">
  <observes element="colorChanger" attribute="style" onbroadcast="alert('La couleur a changé');"/>
</button>

<button label="Observateur"
  oncommand="document.getElementById('colorChanger').setAttribute('style','color: red');"
/>

Deux boutons ont été créé, un nommé Test et l'autre Observateur. Si vous cliquez sur le bouton "Test", rien de spécial n'arrive. Néanmoins, si vous cliquez sur le bouton "Observateur", deux choses arrivent. Premièrement, le texte du bouton passe en rouge, deuxièmement, une boite d'alerte apparait avec le message La couleur a changé.

Ce qui arrive est que le gestionnaire oncommand du second bouton est appelé lorsque l'utilisateur appuie dessus. Le script a ici une référence au broadcaster et change le style de celui-ci afin qu'il ait une couleur (color) rouge. Le broadcaster n'est pas affecté par le changement de style car il n'est pas affiché à l'écran. Néanmoins, le premier bouton a un observateur qui rend compte du changement de style. Les attributs element et attribut sur la balise observes détecte le changement de style. Le style est appliqué automatiquement au premier bouton.

Ensuite, puisque la transmission se fait, le gestionnaire d'évènement onbroadcast est appelé. Il en résulte un message d'alerte qui apparait. Notez que la transmission ne se fait que si l'attribut de style de l'élément broadcaster change. Changer le style du bouton directement ne déclenchera pas la diffusion et la boite d'alerte ne s'affichera pas.

Si vous avez essayé de dupliquer le code pour le premier bouton (button) plusieurs fois, vous auriez vu une série de boites d'alertes, une pour chaque bouton. Ceci car chaque bouton est un observateur et sera prévenu du changement de style.


Nous verrons dans la section suivante comment utiliser les objets XPCOM à partir de XUL et de scripts.