A vegades voleu repetir un conjunt d'opcions per a un nombre arbitrari d'elements. Per exemple, suposeu que voleu implementar un connector per a ordenar un «data.frame». És possible que vulgueu permetre l'ordenació per un nombre arbitrari de columnes (en cas d'enllaços entre les primeres columnes). Això es podria realitzar simplement permetent a l'usuari seleccionar diverses variables en un <varslot> amb multi="true"
. Però si voleu ampliar-ho, p. ex., permetent a l'usuari especificar per a cada variable si s'ha de convertir a caràcter/numèric, o si l'ordenació ha de ser ascendent o descendent, necessitareu més flexibilitat. Altres exemples serien dibuixar diverses línies en un diagrama (permetent seleccionar objecte, estil de línia, color de línia, etc. per a cada línia), o especificar un mapatge per a la recodificació des d'un conjunt de valors antics a valors nous.
Introduïu l'<optionset>. Mirem un exemple senzill, primer:
<dialog [...]> [...] <optionset id="set" min_rows="1"> <content> <row> <input id="firstname" label="Given name(s)" size="small"> <input id="lastname" label="Family name" size="small"> <radio id="gender" label="Gender"> <optioncolumn label="Male" value="m"/> <optioncolumn label="Female" value="f"/> </radio> </row> </content> <optioncolumn id="firstnames" label="Given name(s)" connect="firstname.text"> <optioncolumn id="lastnames" label="Family name" connect="lastname.text"> <optioncolumn id="gender" connect="gender.string"> </optionset> [...] </dialog>
Aquí, hem creat una interfície d'usuari per a especificar un nombre de persones (p. ex., autors). La interfície d'usuari requereix almenys una entrada (min_rows="1"
). Dins de l'element <optionset>, comencem especificant el <content>, és a dir, els elements que pertanyen al conjunt d'opcions. Estareu familiaritzat amb la majoria d'elements dins del <content>.
A continuació, especifiqueu les variables d'interès que voldrem llegir des de l'opció establerta al nostre fitxer JS. Com que ens ocuparem d'un nombre arbitrari d'articles, no podem llegir només getString ("firstname")
en JS. Més aviat, per a cada valor d'interès, especifiqueu un <optioncolumn>. Per a la primera «optioncolumn» a l'exemple, <connect="firstname.text"> significa que el contingut de l'element <input> "firstname" es llegeix per a cada element. Les <optioncolumn> per a la qual es proporciona una label
, es mostrarà a la pantalla, en una columna amb aquesta etiqueta. Al JS, ara podem obtenir els noms de tots els autors utilitzant getList("set.firstname")
, getList("set.lastnames")
pels cognoms, i getList("set.gender")
per a una matriu de cadenes "m"/"f".
Tingueu en compte que no hi ha restriccions sobre el que podeu col·locar dins d'un <optionset>. Fins i tot podeu utilitzar components incrustats. Igual que amb qualsevol altre element, tot el que heu de fer és recollir les variables de sortida d'interès en una especificació <optioncolumn>. En el cas dels connectors incrustats, aquesta és sovint una secció de la propietat "code". P. ex.:
<dialog [...]> [...] <optionset id="set" min_rows="1"> <content> [...] <embed id="color" component="rkward::color_chooser" label="Color"/> </content> [...] <optioncolumn id="color_params" connect="color.code.printout"> </optionset> [...] </dialog>
Per descomptat, també podeu utilitzar la lògica UI dins d'un «optionset». Hi ha dues opcions per a fer això: podeu fer-ho fent la connexió (o creació de scripts) a la secció principal <logic> del connector, com és habitual. No obstant això, accedireu als elements de la IU a la regió de continguts com (p. ex.) «set.contents.firstname.XYZ». Tingueu en compte el prefix "set" (l'id
que heu assignat al conjunt i "contents"). Alternativament, podeu afegir una secció <logic> separada com a element fill de l'<optionset>. En aquest cas, els id
s'adreçaran en relació amb la regió de continguts, p. ex., "firstname.XYZ". Només l'element <script> no està permès a la secció lògica d'un «optionset». Si voleu utilitzar la creació de scripts, haureu d'utilitzar la secció principal <logic> del connector.
Nota
Quan la lògica de creació de scripts en un «optionset», tot el que podeu fer és accedir a la regió de contingut actual. Per tant, normalment, només té sentit connectar elements dins de la regió de contingut entre ells. Connectar una propietat fora de l'<optionset> a una propietat dins de la regió de contingut, pot ser útil per a la inicialització. No obstant això, modificar la regió de contingut després de la inicialització no s'aplicarà als elements que l'usuari ja ha definit. Només a l'element seleccionat actualment en el conjunt.
Fins ara hem considerat un <optionset> que proporciona botons per a afegir/eliminar elements. No obstant això, en alguns casos, és molt més natural seleccionar elements fora de l'<optionset>, i proporcionar només opcions per a personalitzar alguns aspectes de cada element en un <optionset>. Per exemple, suposeu que voleu permetre a l'usuari traçar diversos objectes dins d'un diagrama. Per a cada objecte, l'usuari hauria de poder especificar el color de la línia. Podeu resoldre-ho col·locant un <varselector> i <varslot> dins de l'àrea <content>, permetent a l'usuari seleccionar un element alhora. Tanmateix, significarà menys clics per a l'usuari, si en el seu lloc utilitzeu un <varslot multi="true"> fora de l'<optionset>. A continuació, connectareu aquesta selecció d'objectes a un «optionset» anomenat «driven». Així és com es fa:
<dialog [...]> <logic> <connect client="set.vars" governor="vars.available"/> <connect client="set.varnames" governor="vars.available.shortname"/> </logic> [...] <varselector id="varsel"/> <varslot id="vars" label="Objects to plot"/> <optionset id="set" keycolumn="var"> <content> [...] <embed id="color" component="rkward::color_chooser" label="Line color"/> </content> [...] <optioncolumn id="vars" external="true"> <optioncolumn id="varnames" external="true" label="Variable"> <optioncolumn id="color_params" connect="color.code.printout"> </optionset> [...] </dialog>
Començarem a veure l'exemple a la part inferior. Tindreu en compte que dues especificacions de <optioncolumn> tenen external="true"
. Això li indica al RKWard que estan controlats des de fora de l'<optionset>. Aquí, l'únic motiu de l'opció «optioncolumn» «varnames» és proporcionar etiquetes fàcils de llegir a la pantalla de l'«optionset» (està connectat al modificador «shortname» de la propietat que conté els objectes seleccionats). El motiu de «optioncolumn» «vars» és servir com a columna «key», tal com especifica <optionset keycolumn="vars"...>. Això vol dir que per a cada entrada en aquesta llista, el conjunt oferirà un conjunt d'opcions, i les opcions estan lligades lògicament a aquestes entrades. Aquesta columna està connectada a la propietat que conté els objectes seleccionats a <varslot>. Això és per a cada objecte que hi ha seleccionat, l'<optionset> permetrà especificar el color de la línia.
Nota
La columna externa també pot ser connectada amb connect
a les propietats dins de la regió <content>. No obstant això, és important tenir en compte que les «optioncolumn» declarades external="true"
mai no s'han de modificar des de dins de l'<optionset>, i les «optioncolumn» declarades external="false"
(predeterminat) mai no s'han de modificar des de fora de l'<optionset>.
Els «optionset» són una eina potent, però de vegades poden fer més mal que bé, ja que afegeixen una complexitat considerable, tant des de la perspectiva d'un desenvolupador de connectors, com des de la perspectiva d'un usuari. Per tant, penseu dues vegades, quan les utilitzeu. Aquí teniu un consell:
Per alguns casos simples, l'element <matrix> pot proporcionar una alternativa útil més senzilla.
No feu que la vostra extensió faci massa. Hem donat l'exemple d'utilitzar un «optionset» per a un connector per a dibuixar diverses línies dins d'un diagrama. Però en general no és una bona idea crear un connector que produeixi diagrames individuals per a cada element en un «optionset». Més aviat, feu que el connector produeixi un diagrama, i l'usuari el pot cridar diverses vegades.
Si no espereu més de dos o tres elements en un conjunt, considereu repetir les opcions manualment.