En XOne hay tres tipos de relaciones entre colecciones:

TIPO DE RELACIÓN REPRESENTACIÓN VISUAL DESCRIPCIÓN
Relación de 1 a 1 (Lupa) Utilizado en relaciones con colecciones que tienen muchos datos.
Relación de 1 a 1 (Combo) Utilizado en relaciones con colecciones que tienen pocos datos.
Relación de 1 a Varios (Contents) Utilizado cuando no sabemos el número de registros que podemos asociar. Un ejemplo típico de contents son los Pedidos y sus detalles.


Este tipo de relación se utiliza para seleccionar un único valor de otra colección.

Únicamente se grabará en Base de Datos el ID de la fila seleccionada, pudiendo rescatar además, simplemente para mostrar en pantalla, otros campos de la fila seleccionada.


Vista campo de enlace de tipo Lupa en Pocket PC
Vista campo de enlace de tipo Lupa en BlackBerry
	<prop name="IDCLIENTE" group="1" type="N" visible="0" mapcol="Clientes" mapfld="ID"/>
	<!-- 
		Este campo es el que realmente SE GRABARÁ en la BD, normalmente no está visible.
		Enlaza con la colección "Clientes" y nos guardaremos el valor del campo "ID" seleccionado.
	-->
 
	<prop name="MAP_CLIENTE" ... linkedto="IDCLIENTE" linkedfield="NOMBRE" onchange="Refresh" value="##ID##">Cliente</prop>
	<prop name="MAP_CONTACTO" ... linkedto="IDCLIENTE" linkedfield="CONTACTO" locked="true" onchange="Refresh">Contacto</prop>
	<!-- 
		Estos campos están asociados con el campo "IDCLIENTE". Al llevar el prefijo "MAP_" NO se graban en BD.
		Para obtener sus valores utilizan el campo "IDCLIENTE" (linkedto) como enlace a la otra colección.
		El linkedfield es el campo que mostraremos por pantalla, el cual nos traemos de la otra colección.
		La lupa aparece en el campo que no está locked="true", para poder buscar directamente desde él.
		Los demás campos podemos ponerlos con el locked="true" para que NO se pueda editar su contenido NI TAMPOCO salga la lupa.
	-->


Similar al anterior, pero se utiliza únicamente cuando la colección llamada tiene pocos datos.

Esto es importante, porque cuando se va a pintar la ventana de edición, y uno de los campos tiene un combo, cargará en memoria todos los valores que puede contener dicho combo, con lo que si son muchos datos a cargar en el momento de abrir dicha ventana de edición, puede demorarse bastante.


Vista campo de enlace de tipo Lupa en Pocket PC
Vista campo de enlace de tipo Lupa en BlackBerry

Ejemplo de Código

	<prop name="IDTIPO" group="1" type="N" visible="0" mapcol="Tiposvisitas" mapfld="ID"></prop>
		<!-- 
			Este campo es el que realmente SE GRABARA BD, normalmente no está visible.
			Enlaza con la colección "TiposVisitas" y nos guardaremos el valor del campo "ID" seleccionado.
		-->
 
	<prop name="MAP_TIPO" ... type="T" linkedto="IDTIPO" linkedfield="DESCRIPCION" showinline="true">Tipo</prop>
		<!-- 
			Este campo está asociado con el campo "IDTIPO". Al llevar el prefijo "MAP_" NO se graba en BD.
			Para obtener sus valores utiliza el campo "IDTIPO" como enlace a la otra colección.
			La diferencia con el control tipo "lupa" es el atributo showinline="true", que es realmente
			el que le da la apariencia de combo. 
		-->

La diferencia con el tipo lupa es simplemente el atributo showinline=“true” y además el hecho de que el combo se carga de valores cuando se entra en la colección a diferencia de la lupa.


La estructura es similar a los anteriores, pero se utiliza exclusivamente cuando la colección llamada tiene pocos datos y claramente definidos.
NO se tira contra una Tabla en Base de Datos, los valores se definen en un primer PROP y se rescatan en otro PROP.

Ejemplo de Código


<prop name="MAP_IDTIPO" visible="0" group="1" type="N" mapcol-values="COMERCIAL,DPT INTRODUCCION,RESPONSABLE S EXT"/>
<!--
   Al ser un MAP_ no se graba en BD y el atributo mapcol-values define los valores posibles, separados por comas.
-->
<prop name="DESTINATARIO" labelwidth="0" type="T" size="40" onchange="Refresh" fieldsize="23" visible="1" showinline="true" group="1" linkedto="MAP_IDTIPO" linkedfield="DATA"/>
<!--
   Este campo es el que se graba en BD, el atributo linkedfield siempre vale DATA.
-->


Una colección de contenido (contents) es un grupo de datos que dependen de una cabecera, es decir, una colección que depende de otra.

Se utiliza cuando no sabemos el número de registros que vamos a poder asociar en la colección cabecera.

Ejemplos típicos de contents son los pedidos y sus líneas de detalle o artículos y sus existencias en almacén.



Campo de enlace entre la cabecera
y la colección de detalles(contents)


Para definir colección con content es necesario seguir varios pasos:


Se debe definir la colección principal (p.e colección de documentos). Cada una de las propiedades que se definen en esta colección corresponde a la cabecera del objeto.

Se define la colección content.

En el ejemplo que estamos utilizando, se creará una colección de detalles de documento. Cada una de las propiedades que se definan en la colección, corresponderán a las líneas de detalle del documento.

Se incluye una definición de content en la colección principal. La definición de content tiene el siguiente formato:

    <prop name="@NombrePropiedad" group="NumeroGrupo" type="Z" contents="nombre del content"></prop>
    <contents name="nombre del content" src="coleccion" filter="sentencia WHERE"></contents>
PROPS
name Le asigna un nombre a la propiedad. Se suele poner una “@” delante para indicar que es una propiedad que hace referencia a un content. Recomendamos su uso para distinguir y localizar con mayor facilidad dentro del mappings.
group Grupo o pestaña donde aparecerá el content.
type Tipo de propiedad. Para referirse a content ha de ser “Z”.
contents Nombre del content. Este atributo hace una llamada al nodo contents que tenga su mismo nombre. Es decir, el atributo contents ha de ser igual que el name del nodo contents.
width Define el ancho del content.
height Define la altura del content. En Android, es posible modificar este atributo por script. Supongamos que por ejemplo necesitas un cuadro de búsqueda que está oculto y que lo activas con un botón, y quieres que todo ocupe siempre el 100% de la pantalla. Entonces, lo que harías sería lo siguiente:


    <prop name="MAP_TAMCONTENT" visible="0" frame="id1" group="1" type="T" size="30" title="Tamaño content" />
    <prop name="@MaquinasContent" frame="id4" group="1" type="Z" contents="MaquinasContent" width="100%" height="##FLD_MAP_TAMCONTENT##" onchange="Refresh" editmodal="true" forceonchange="true" mask="0" locked="true" />
    <contents name="MaquinasContent" src="MaquinasContent" filter="IDCLIENTE=##FLD_MAP_IDCLIENTE##" />
<before-edit>
    <action name="runscript">
        <script language="VBScript">
            this("MAP_TAMCONTENT")="75%"
        <script>
    </action>
<before-edit>

Ahora, mediante script modificarías el tamaño cuando quisieras del mismo modo.

CONTENTS
name Le asigna un nombre al content. Todo content tiene que tener un nombre, que deberá coincidir con el atributo contents, del punto anterior.
src Indica el nombre de la colección contents. Cada vez que se crea un objeto contenedor, la colección origen es copiada y se llena con aquellos objetos que le pertenezcan al contenedor únicamente. En el ejemplo que estamos poniendo (documento con líneas de detalle) el objeto contenedor es el documento (un objeto por cada registro de cabecera). Cada objeto contenedor tiene asignadas varias líneas de detalle (en una tabla enlazada) Los registros de la tabla enlazada se colocan en la colección de contenidos.
filter Es el filtro que indica cuáles registros de la tabla enlazada le “pertenecen” a este objeto en particular. Si la tabla de detalles se enlaza con la tabla principal por el campo IDDOCUMENTO, el filtro sería algo como IDDOCUMENTO=##ID##. Los componentes de datos se encargarán de sustituir la macro ##ID## por el ID del objeto propietario para cada uno de los documentos.



Si lo que se quiere es enlazar el pedido con los detalles en el momento de grabar el pedido(padre), se definen las acciones necesarias para que durante la grabación del pedido se realicen los enlaces necesarios, para que en las tablas queden almacenados los valores correctos que determinen la relación entre los registros del detalle y el pedido en la Base de Datos.

Los códigos siguientes tienen el sentido de asignar al campo IDPEDIDO de los detalles el valor del ID del pedido de la colección de cabecera, de forma que queden enlazados los registros. (relación cabecera-detalles)


En la colección Pedidos (padre) habría que añadir el siguiente código:

<insert>
  <!-- Al grabar un nuevo pedido en base de datos, a cada detalle se le pone el ID 
  del pedido creado -->
  <action name="link" coll="Detalles" field="IDPEDIDO" value="##ID##"></action>
</insert>


En la colección Detalles (colección contenida ó hija) habría que añadir el siguiente código:

<create>
    <!-- Al crear una nueva línea de Detalle, al IDPEDIDO de ese detalle se le pone 
      el ID del PEDIDO que estamos realizando -->
    <action name="setfldval" targetfld="IDPEDIDO" sourcefld="ID"></action>
</create>



Ejemplo de un combo para seleccionar la comunidad autónoma a la que pertenece un cliente:

<!-- Este código estaría en la colección "principal" de clientes, donde queremos el combo de valores -->
	<!-- Propiedad de tipo IDENLACE con otra colección -->
	<prop name="IDCOMUNIDAD" visible="0" type="N" mapcol="Comunidades" mapfld="ID"/>
 
        <!-- Propiedad de tipo MAPEADA -->
        <prop name="MAP_COMUNIDAD" type="T" labelwidth="8" title="COMUNIDAD" linkedto="IDCOMUNIDAD" linkedfield="NOMBRE" showinline="true"/>



Aquí tenemos la definición de la colección que aparece dentro de dicho combo.

<coll name="Comunidades" sql="SELECT * FROM ##PREF##Comunidades" objname="Comunidades" updateobj="Comunidades" progid="ASData.CASBasicDataObj" filter="" sort="">
	<group name="General" id="1">
		<prop name="NOMBRE" type="T" title="Comunidad:" width="90%" lmargin="5%" labelwidth="6" visible="15" />
	</group>
</coll>