Saltar al contenido principal
Versión: 20 R5 BETA

Componentes de desarrollo

A 4D component is a set of 4D functions, methods, and forms representing one or more functionalities that can be installed and used in 4D applications. Por ejemplo, puede desarrollar un componente 4D de correo electrónico que gestione todos los aspectos del envío, la recepción y el almacenamiento de correos electrónicos en aplicaciones 4D.

Puede desarrollar componentes 4D para sus propias necesidades y mantenerlos en privado. You can also share your components with the 4D community.

Definiciones

  • Matrix Project: 4D project used for developing the component. El proyecto matriz es una base estándar sin atributos específicos. Un proyecto matricial forma un único componente.
  • Host Project: Application project in which a component is installed and used.
  • Component: Matrix project that can be compiled or built, copied into the Components folder of the host application and whose contents are used in the host application.

Básicos

La creación e instalación de los componentes 4D se realiza directamente desde 4D:

  • To install a component, you simply need to copy the component files into the Components folder of the project. Puede utilizar alias o atajos.
  • Un proyecto puede ser a la vez matriz y local, es decir, que un proyecto matriz puede utilizar a su vez uno o varios componentes. Sin embargo, un componente no puede utilizar subcomponentes por sí mismo.
  • Un componente puede llamar a la mayoría de los elementos de 4D: clases, funciones, métodos proyecto, formularios proyecto, barras de menú, listas de selección, etc. No puede llamar a los métodos base ni a los triggers.
  • No es posible utilizar el datastore, las tablas estándar o los archivos de datos en los componentes 4D. Sin embargo, un componente puede crear y/o utilizar tablas, campos y archivos de datos utilizando mecanismos de bases externas. Se trata de bases 4D independientes con las que se trabaja utilizando comandos SQL.
  • Un proyecto local que se ejecuta en modo interpretado puede utilizar componentes interpretados o compilados. Un proyecto local que se ejecuta en modo compilado no puede utilizar componentes interpretados. En este caso, sólo se pueden utilizar componentes compilados.

Alcance de los comandos del lenguaje

Except for Unusable commands, a component can use any command of the 4D language.

When commands are called from a component, they are executed in the context of the component, except for the EXECUTE METHOD or EXECUTE FORMULA command that use the context of the method specified by the command. También hay que tener en cuenta que los comandos de lectura del tema "Usuarios y grupos" se pueden utilizar desde un componente, pero leerán los usuarios y grupos del proyecto local (un componente no tiene sus propios usuarios y grupos).

The SET DATABASE PARAMETER and Get database parameter commands are an exception: their scope is global to the application. Cuando estos comandos se llaman desde un componente, se aplican al proyecto de la aplicación local.

Furthermore, specific measures have been specified for the Structure file and Get 4D folder commands when they are used in the framework of components.

The COMPONENT LIST command can be used to obtain the list of components that are loaded by the host project.

Comandos no utilizables

Los siguientes comandos no son compatibles para su uso dentro de un componente porque modifican el archivo de estructura - que está abierto en sólo lectura. Su ejecución en un componente genera el error -10511, "El comando CommandName no puede ser llamado desde un componente":

  • ON EVENT CALL
  • Method called on event
  • SET PICTURE TO LIBRARY
  • REMOVE PICTURE FROM LIBRARY
  • SAVE LIST
  • ARRAY TO LIST
  • EDIT FORM
  • CREATE USER FORM
  • DELETE USER FORM
  • CHANGE PASSWORD
  • EDIT ACCESS
  • Set group properties
  • Set user properties
  • DELETE USER
  • CHANGE LICENSES
  • BLOB TO USERS
  • SET PLUGIN ACCESS

Notas:

  • The Current form table command returns Nil when it is called in the context of a project form. Por consiguiente, no puede utilizarse en un componente.
  • SQL data definition language commands (CREATE TABLE, DROP TABLE, etc.) cannot be used on the component project. However, they are supported with external databases (see CREATE DATABASE SQL command).

Compartir métodos proyecto

Todos los métodos proyecto de un proyecto matricial son por definición incluidos en el componente (el proyecto es el componente), lo que significa que pueden ser llamados y ejecutados dentro del componente.

Por otro lado, por defecto estos métodos proyecto no serán visibles, y no podrán ser llamados por el proyecto local. In the matrix project, you must explicitly designate the methods that you want to share with the host project by checking the Shared by components and host project box in the method properties dialog box:

Los métodos proyecto compartidos se pueden llamar en el código del proyecto local (pero no se pueden modificar en el editor de código del proyecto local). These methods are entry points of the component.

Por el contrario, por razones de seguridad, por defecto un componente no puede ejecutar métodos proyecto que pertenezcan al proyecto local. En algunos casos, puede ser necesario permitir que un componente acceda a los métodos proyecto de su proyecto local. To do this, you must explicitly designate which project methods of the host project you want to make accessible to the components (in the method properties, check the Shared by components and host project box).

Once the project methods of the host projects are available to the components, you can execute a host method from inside a component using the EXECUTE FORMULA or EXECUTE METHOD command. Por ejemplo:

// Método local
component_method("host_method_name")
// component_method
#DECLARE ($param : Text)
EXECUTE METHOD($param)

Una base local interpretada que contenga componentes interpretados puede ser compilada o verificada sintácticamente si no llama a métodos del componente interpretado. De lo contrario, aparecerá una caja de diálogo de advertencia cuando intente iniciar la compilación o una comprobación de sintaxis y no será posible realizar la operación.\ Keep in mind that an interpreted method can call a compiled method, but not the reverse, except via the use of the EXECUTE METHOD and EXECUTE FORMULA commands.

Compartir las clases y las funciones

Por defecto, las clases y funciones de los componentes no pueden ser llamadas desde el editor de código 4D del proyecto local. Si quiere exponer las clases y funciones del componente en el proyecto local, necesita declarar un espacio de nombres del componente. Además, puede controlar cómo se sugieren las clases y funciones de los componentes en el Editor de código local.

Declaración del namespace

To allow classes and functions of your component to be exposed in the host projects, enter a value in the Component namespace in the class store option in the General page of the matrix project Settings. Por defecto, el área está vacía: las clases de componentes no están disponibles fuera del contexto de los componentes.

A namespace ensures that no conflict emerges when a host project uses different components that have classes or functions with identical names. A component namespace must be compliant with property naming rules.

When you enter a value, you declare that component classes and functions will be available in the user class store (cs) of the host project's code, through the cs.<value> namespace. For example, if you enter "eGeometry" as component namespace, assuming that you have created a Rectangle class containing a getArea() function, once your project is installed as a component, the developer of the host project can write:

//en el proyecto local
var $rect: cs.eGeometry.Rectangle
$rect:=cs.eGeometry.Rectangle.new(10;20)
$area:=$rect.getArea()
info

The namespace of a compiled component will be added between parentheses after the component name in the Component Methods page of the host projects:

Por supuesto, se recomienda utilizar un nombre distintivo para evitar cualquier conflicto. Si en el proyecto ya existe una clase usuario con el mismo nombre que un componente, se tiene en cuenta la clase usuario y se ignoran las clases del componente.

Las clases ORDA de un componente no están disponibles en el proyecto local. Por ejemplo, si hay una dataclass llamada Employees en su componente, no podrá utilizar una clase "cs.Mycomponent.Employee" en el proyecto local.

Clases ocultas

Como en todo proyecto, puede crear clases y funciones ocultas en el componente anteponiendo a los nombres un guión bajo ("_"). When a component namespace is defined, hidden classes and functions of the component will not appear as suggestions when using code completion.

Sin embargo, hay que tener en cuenta que pueden seguir utilizándose si se conocen sus nombres. For example, the following syntax is valid even if the _Rectangle class is hidden:

$rect:=cs.eGeometry._Rectangle.new(10;20)

Non-hidden functions inside a hidden class appear as suggestions when you use code completion with a class that inherits from it. For example, if a component has a Teacher class that inherits from a _Person class, code completion for Teacher suggests non-hidden functions from _Person.

Completar el código de los componentes compilados

To make your component easier to use for developers, you can check the Generate syntax file for code completion when compiled option in the General page of the matrix project Settings.

A syntax file (JSON format) is then automatically created during the compilation phase, filled with the syntax of your component's classes, functions, and exposed methods, and placed in the \Resources\en.lproj folder of the component project. 4D utiliza el contenido de ese archivo de sintaxis para generar ayuda contextual en el editor de código, como la finalización del código y la sintaxis de las funciones:

If you don't enter a component namespace, the resources for the classes and exposed methods are not generated even if the syntax file option is checked.

Paso de variables

Las variables locales, proceso e interproceso no se comparten entre los componentes y los proyectos locales. La única forma de modificar las variables del componente desde el proyecto local y viceversa es utilizando punteros.

Ejemplo utilizando un array:

//In the host project:
ARRAY INTEGER(MyArray;10)
AMethod(->MyArray)

//In the component, the AMethod project method contains:
APPEND TO ARRAY($1->;2)

Ejemplos utilizando variables:

C_TEXT(myvariable)
component_method1(->myvariable)
C_POINTER($p)
$p:=component_method2(...)

Sin un puntero, un componente puede seguir accediendo al valor de una variable de la base local (pero no a la propia variable) y viceversa:

//En la base local
C_TEXT($input_t)
$input_t:="DoSomething"
component_method($input_t)
// component_method obtiene "DoSomething" en $1 (pero no la variable $input_t)

Cuando se utilizan punteros para que los componentes y el proyecto local se comuniquen, hay que tener en cuenta las siguientes particularidades:

  • The Get pointer command will not return a pointer to a variable of the host project if it is called from a component and vice versa.

  • La arquitectura de componentes permite la coexistencia, dentro del mismo proyecto interpretado, de componentes interpretados y compilados (a la inversa, en un proyecto compilado sólo pueden utilizarse componentes compilados). Para utilizar punteros en este caso, debe respetar el siguiente principio: el intérprete puede desanclar un puntero construido en modo compilado; sin embargo, en modo compilado, no puede desanclar un puntero construido en modo interpretado. Ilustremos este principio con el siguiente ejemplo: dados dos componentes, C (compilado) e I (interpretado), instalados en el mismo proyecto local.

  • If component C defines the myCvar variable, component I can access the value of this variable by using the pointer ->myCvar.

  • If component I defines the myIvar variable, component C cannot access this variable by using the pointer ->myIvar. Esta sintaxis provoca un error de ejecución.

  • The comparison of pointers using the RESOLVE POINTER command is not recommended with components since the principle of partitioning variables allows the coexistence of variables having the same name but with radically different contents in a component and the host project (or another component). El tipo de la variable puede incluso ser diferente en ambos contextos. If the myptr1 and myptr2 pointers each point to a variable, the following comparison will produce an incorrect result:

     RESOLVE POINTER(myptr1;vVarName1;vtablenum1;vfieldnum1)
RESOLVE POINTER(myptr2;vVarName2;vtablenum2;vfieldnum2)
If(vVarName1=vVarName2)
//Esta prueba devuelve True aunque las variables sean diferentes

En este caso, es necesario utilizar la comparación de punteros:

     If(myptr1=myptr2) //Esta prueba devuelve False

Gestión de errores

An error-handling method installed by the ON ERR CALL command only applies to the running application. In the case of an error generated by a component, the ON ERR CALL error-handling method of the host project is not called, and vice versa.

Acceso a las tablas del proyecto local

Aunque los componentes no pueden utilizar tablas, los punteros pueden permitir que los proyectos locales y los componentes se comuniquen entre sí. Por ejemplo, este es un método que podría ser llamado desde un componente:

// calling a component method
methCreateRec(->[PEOPLE];->[PEOPLE]Name;"Julie Andrews")

Within the component, the code of the methCreateRec method:

C_POINTER($1) //Pointer on a table in host project
C_POINTER($2) //Pointer on a field in host project
C_TEXT($3) // Value to insert

$tablepointer:=$1
$fieldpointer:=$2
CREATE RECORD($tablepointer->)

$fieldpointer->:=$3
SAVE RECORD($tablepointer->)

En el contexto de un componente, 4D asume que una referencia a un formulario tabla es una referencia al formulario tabla local (ya que los componentes no pueden tener tablas.)

Uso de tablas y campos

Un componente no puede utilizar las tablas y campos definidos en la estructura 4D del proyecto matriz. Sin embargo, puede crear y utilizar bases externas, y luego utilizar sus tablas y campos según sus necesidades. Puede crear y gestionar bases externas utilizando SQL. Sin embargo, puede crear y utilizar bases externas, y luego utilizar sus tablas y campos según sus necesidades. Utilizar una base externa significa designar temporalmente esta base como base actual, es decir, como la base de destino para las consultas SQL ejecutadas por 4D. You create external databases using the SQL CREATE DATABASE command.

Ejemplo

El siguiente código se incluye en un componente y realiza tres acciones básicas con una base de datos externa:

  • creación de la base de datos externa si aún no existe,
  • añade datos a la base de datos externa,
  • lectura de datos desde la base de datos externa.

Creación de la base de datos externa:

<>MyDatabase:=Get 4D folder+"\MyDB" // (Windows) stores the data in an authorized directory
Begin SQL
CREATE DATABASE IF NOT EXISTS DATAFILE :[<>MyDatabase];
USE DATABASE DATAFILE :[<>MyDatabase];
CREATE TABLE IF NOT EXISTS KEEPIT
(
ID INT32 PRIMARY KEY,
kind VARCHAR,
name VARCHAR,
code TEXT,
sort_order INT32
);

CREATE UNIQUE INDEX id_index ON KEEPIT (ID);

USE DATABASE SQL_INTERNAL;

End SQL

Escritura en la base de datos externa:

 $Ptr_1:=$2 // retrieves data from the host project through pointers
$Ptr_2:=$3
$Ptr_3:=$4
$Ptr_4:=$5
$Ptr_5:=$6
Begin SQL

USE DATABASE DATAFILE :[<>MyDatabase];

INSERT INTO KEEPIT
(ID, kind, name, code, sort_order)
VALUES
(:[$Ptr_1], :[$Ptr_2], :[$Ptr_3], :[$Ptr_4], :[$Ptr_5]);

USE DATABASE SQL_INTERNAL;


End SQL

Lectura en una base de datos externa:

 $Ptr_1:=$2 // accesses data of the host project through pointers
$Ptr_2:=$3
$Ptr_3:=$4
$Ptr_4:=$5
$Ptr_5:=$6

Begin SQL

USE DATABASE DATAFILE :[<>MyDatabase];

SELECT ALL ID, kind, name, code, sort_order
FROM KEEPIT
INTO :$Ptr_1, :$Ptr_2, :$Ptr_3, :$Ptr_4, :$Ptr_5;

USE DATABASE SQL_INTERNAL;

End SQL

Utilización de formularios

  • Sólo los "formularios de proyecto" (formularios que no están asociados a ninguna tabla específica) pueden utilizarse en un componente. Sólo los "formularios de proyecto" (formularios que no están asociados a ninguna tabla específica) pueden utilizarse en un componente.
  • Un componente puede llamar a formularios tabla del proyecto local. Tenga en cuenta que en este caso es necesario utilizar punteros en lugar de nombres de tablas entre paréntesis [] para especificar los formularios en el código del componente.

If a component uses the ADD RECORD command, the current Input form of the host project will be displayed, in the context of the host project. Por consiguiente, si el formulario incluye variables, el componente no tendrá acceso a ellas.

  • You can publish component forms as subforms in the host projects. Esto significa que puede, más concretamente, desarrollar componentes que ofrezcan objetos gráficos. Por ejemplo, los Widgets que ofrece 4D se basan en el uso de subformularios en los componentes.

En el contexto de un componente, cualquier formulario de proyecto referenciado debe pertenecer al componente. For example, inside a component, referencing a host project form using DIALOG or Open form window will throw an error.

Utilización de recursos

Los componentes pueden utilizar recursos situados en la carpeta Resources del componente.

Los mecanismos automáticos son operacionales: los archivos XLIFF encontrados en la carpeta Resources de un componente serán cargados por este componente.

En un proyecto local que contiene uno o más componentes, cada componente, así como los proyectos locales, tiene su propia "cadena de recursos." Los recursos están divididos entre las diferentes proyectos: no es posible acceder a los recursos del componente A desde el componente B o desde el proyecto local.

Ejecución del código de inicialización

Un componente puede ejecutar automáticamente código 4D al abrir o cerrar la base local, por ejemplo para cargar y/o guardar las preferencias o los estados usuario relacionados con el funcionamiento de la base local.

Executing initialization or closing code is done by means of the On Host Database Event database method.

For security reasons, you must explicitly authorize the execution of the On Host Database Event database method in the host database in order to be able to call it. To do this, you must check the Execute "On Host Database Event" method of the components option in the Security page of the Settings.

Protección de los componentes: compilación

Por defecto, todo el código de un proyecto matriz instalado como componente es potencialmente visible desde el proyecto local. En particular:

  • Los métodos proyecto compartido se encuentran en la Página Métodos del Explorador y pueden ser llamados en los métodos del proyecto local. Su contenido puede ser seleccionado y copiado en el área de vista previa del Explorador. También se pueden ver en el depurador. Sin embargo, no es posible abrirlos en el Editor de código ni modificarlos.
  • Los otros métodos proyecto del proyecto matriz no aparecen en el Explorador, pero también pueden verse en el depurador del proyecto local.
  • The non-hidden classes and functions can be viewed in the debugger if a namespace is declared.

To protect the code of a component effectively, simply compile and build the matrix project and provide it in the form of a .4dz file. Cuando se instala un proyecto matricial compilado como un componente:

  • Los métodos, clases y funciones del proyecto compartido pueden ser llamados desde los métodos proyecto locales y también se muestran en la página de métodos del Explorador. Sin embargo, su contenido no aparecerá en el área de vista previa ni en el depurador.
  • Los otros métodos proyecto del proyecto matriz nunca aparecerán.

Compartir componentes

We encourage you to support the 4D developer community by sharing your components, preferably on the GitHub platform. We recommend that you use the 4d-component topic to be correctly referenced.