Composite Components
El componente Composite
combina componentes existentes de webforJ en componentes reutilizables y auto contenidos con comportamiento personalizado. Úsalo para envolver componentes internos de webforJ en unidades de lógica de negocio reutilizables, reutilizar patrones de componentes en toda tu aplicación y combinar múltiples componentes sin exponer detalles de implementación.
Un componente Composite
tiene una fuerte asociación con un componente vinculado subyacente. Esto te da control sobre qué métodos y propiedades pueden acceder los usuarios, a diferencia de la herencia tradicional donde todo está expuesto.
Si necesitas integrar componentes web de otra fuente, utiliza alternativas especializadas:
- ElementComposite: Para componentes web con gestión de propiedades con tipo seguro.
- ElementCompositeContainer: Para componentes web que aceptan contenido slotado.
Uso
Para definir un componente Composite
, extiende la clase Composite
y especifica el tipo de componente que gestiona. Esto se convierte en tu componente vinculado, que es el contenedor raíz que sostiene tu estructura interna:
public class BasicComposite extends Composite<FlexLayout> {
public BasicComposite() {
// Accede al componente vinculado para configurarlo
getBoundComponent()
.setDirection(FlexDirection.COLUMN)
.setSpacing("3px")
.add(new TextField(), new Button("Enviar"));
}
}
El método getBoundComponent()
proporciona acceso a tu componente subyacente, lo que te permite configurar sus propiedades, agregar componentes hijos y gestionar su comportamiento directamente.
El componente vinculado puede ser cualquier componente de webforJ o componente de elemento HTML. Para diseños flexibles, considera usar FlexLayout
o Div
como tu componente vinculado.
Nunca extiendas Component
o DwcComponent
directamente. Siempre usa patrones de composición con Composite
para construir componentes personalizados.
Sobrescribe initBoundComponent()
cuando necesites mayor flexibilidad para crear y gestionar el componente vinculado, como usar constructores parametrizados en lugar del constructor por defecto sin argumentos. Usa este patrón cuando el componente vinculado requiera que se le pasen componentes a su constructor en lugar de agregarlos después.
public class CustomFormLayout extends Composite<FlexLayout> {
private TextField nameField;
private TextField emailField;
private Button submitButton;
@Override
protected FlexLayout initBoundComponent() {
nameField = new TextField("Nombre");
emailField = new TextField("Correo electrónico");
submitButton = new Button("Enviar");
FlexLayout layout = new FlexLayout(nameField, emailField, submitButton);
layout.setDirection(FlexDirection.COLUMN);
layout.setSpacing("10px");
return layout;
}
}
Ciclo de vida del componente
webforJ maneja automáticamente toda la gestión del ciclo de vida para componentes Composite
. Al usar el método getBoundComponent()
, la mayoría del comportamiento personalizado se puede manejar en el constructor, incluyendo la adición de componentes hijos, establecimiento de propiedades, configuración básica de diseño y registro de eventos.
public class UserDashboard extends Composite<FlexLayout> {
private TextField searchField;
private Button searchButton;
private Div resultsContainer;
public UserDashboard() {
initializeComponents();
setupLayout();
configureEvents();
}
private void initializeComponents() {
searchField = new TextField("Buscar usuarios...");
searchButton = new Button("Buscar");
resultsContainer = new Div();
}
private void setupLayout() {
FlexLayout searchRow = new FlexLayout(searchField, searchButton);
searchRow.setAlignment(FlexAlignment.CENTER);
searchRow.setSpacing("8px");
getBoundComponent()
.setDirection(FlexDirection.COLUMN)
.add(searchRow, resultsContainer);
}
private void configureEvents() {
searchButton.onClick(event -> performSearch());
}
private void performSearch() {
// Lógica de búsqueda aquí
}
}
Si tienes requisitos específicos adicionales de configuración o limpieza, es posible que necesites usar los ganchos de ciclo de vida opcionales onDidCreate()
y onDidDestroy()
:
public class DataVisualizationPanel extends Composite<Div> {
private Interval refreshInterval;
@Override
protected void onDidCreate(Div container) {
// Inicializa componentes que requieren adjunto al DOM
refreshInterval = new Interval(5.0, event -> updateData());
refreshInterval.start();
}
@Override
protected void onDidDestroy() {
// Limpieza de recursos
if (refreshInterval != null) {
refreshInterval.stop();
}
}
private void updateData() {
// Lógica de actualización de datos
}
}
Si necesitas realizar cualquier acción después de que el componente se adjunta al DOM, usa el método whenAttached()
:
public class InteractiveMap extends Composite<Div> {
public InteractiveMap() {
setupMapContainer();
whenAttached().thenAccept(component -> {
initializeMapLibrary();
loadMapData();
});
}
}
Ejemplo de componente Composite
El siguiente ejemplo demuestra una aplicación de To-Do donde cada ítem es un componente Composite
que consiste en un RadioButton
estilizado como un interruptor y un Div con texto:
Mostrar Código
- Java
- CSS
Ejemplo: Agrupamiento de componentes
A veces, puede que quieras usar un Composite
para agrupar componentes relacionados en una sola unidad, incluso cuando la reutilización no sea la principal preocupación:
Mostrar Código
- Java
- CSS