AX7 - 5/5 DataInteractorFactory Class

Esta clase junto a otras modificaciones nos permitirán en un lookup filtrar por dos campos distintos asignados previamente.

Haremos un ejemplo empezando desde zero.

Nos crearemos la tabla FarmerTable y un EDT de tipo string llamado FarmerId; en la tabla FarmerTable, agregaremos el EDT FarmerId,



En el EDT FarmerId asignamos la referencia a la tabla FarmerTable y creamos su relación.




Agregaremos algunos campos más a la tabla entre los que estará el campo Name.




En el grupo de campos AutoLookup añadiremos los campos que queremos que se muestren en el desplegable.





Para probar lo que estamos haciendo, nos crearemos un formulario y agregaremos un control de tipo formStringControl; y en su propiedad extended data types, le indicamos que utilice el FarmerId.




Recordad de asignar el formulario como objeto que arranca en el proyecto.




Si ejecutamos, nos encontraremos que nuestro formulario tiene un desplegable como el que se muestra en la imagen. 



Si escribimos algo en el lookup nos filtrará por el campo principal.



Si intentamos escribir parte del nombre veremos que nos indica que no existe un valor que se corresponda.




La clase DataInteractorFactory

Para poder crear un lookup que nos permita filtrar por dos campos distintos, deberemos seguir los pasos que se comentarán a continuación. 
Nos crearemos una clase que extienda de la clase DataInteractorFactory y deberemos implementar algunos métodos.

class FarmerDataInteractionFactory extends DataInteractorFactory
{
    public AmbiguousReferenceResolver constructAmbiguousReferenceResolver()
    {
        return AmbiguousReferenceResolver::construct(this.dataInteractorTarget(), FarmerDataInteractionFactory::getPkFieldBinding());
    }

    public static AmbiguousReferenceResolver useExistingOrCreateResolver(FormControl _control, Query _baseQuery = null)
    {
        var pkFieldBinding = FarmerDataInteractionFactory::getPkFieldBinding();

        if (_baseQuery)
        {
            return new FormControlAmbiguousReferenceResolver(_control, pkFieldBinding, null, _baseQuery);
        }
       
        return FormControlAmbiguousReferenceResolver::useExistingOrCreate(_control, pkFieldBinding, null, _baseQuery);
    }

    public static str resolveAmbiguousReferenceForControl(FormControl _control, Query _baseQuery = null)
    {
        return FarmerDataInteractionFactory::useExistingOrCreateResolver(_control, _baseQuery)
                .resolveAmbiguousReference(true);
    }

    public static Query constructDefaultBaseQuery()
    {
        var query = new Query();

        // add the root DS
        var FarmerTableDS = query.addDataSource(tableNum(FarmerTable));
       
        return query;
    }

    public static AbsoluteFieldBinding getPkFieldBinding()
    {
        return AbsoluteFieldBinding::construct(fieldStr(FarmerTable, FarmerId), tableStr(FarmerTable));
    }

}


Los más importantes son: el método constructDefaultBaseQuery, que como os imaginareis, será donde crearemos la query del lookup; y el método getPKFieldBinding donde le indicaremos el campo primario de la tabla.


 public static Query constructDefaultBaseQuery()
    {
        var query = new Query();

        // add the root DS
        var FarmerTableDS = query.addDataSource(tableNum(FarmerTable));
       
        return query;
    }

    public static AbsoluteFieldBinding getPkFieldBinding()
    {
        return AbsoluteFieldBinding::construct(fieldStr(FarmerTable, FarmerId), tableStr(FarmerTable));
    }


El siguiente paso será asignarle la clase que acabamos de crear a la propiedad DataInteractorFactory Class del extended Data Type.




Con esto no hemos finalizado el trabajo; en el desplegable podremos buscar por dos campos y para que el sistema conozca porque dos campos puede filtrar, estos han de ser asignados a las propiedades Title Field 1 y 2 de la tabla.

En la imagen se observa que he asignado el identificador del granjero y el nombre.



Todavía falta un punto para que el lookup funcione correctamente, y es que por cada uno de los campos con los que queramos filtrar, deberá tener su propio índice.


No sirve tener los dos campos en un mismo índice; cada campo debe tener el suyo propio.

Ahora, repitiendo el primer ejemplo, si introducimos un Id de granjero veremos como el lookup se filtra automáticamente.


Y si filtramos por un nombre, el lookup funcionará igual.


He tomado dos campos de tipo string para los filtros, pero eso no implica que no puedan utilizarse otro tipo de campos, por ejemplo, un enumerado.




Filtrando por el enumerado.


Nota importante: aquí tenemos todos los registros actuales de la tabla, como se puede ver, existe un granjero cuyo id es All.


Si nosotros, en el filtro le indicamos All, la query filtra primero por el campo Title Field1; y en caso de no encontrar nada, buscará por el 2


Con esto quiero decir que el lookup no filtra por los dos campos a la vez,


Comentarios