跳至主要内容

组件组合

在 ChatGPT 中打开
Java API

Composite 组件将现有的 webforJ 组件组合成自包含、可重用的组件,并具备自定义行为。使用它可以将内部 webforJ 组件包装成可重用的业务逻辑单元,在您的应用中重用组件模式,并结合多个组件而不会暴露实现细节。

Composite 组件与其底层绑定组件有着紧密的关联。这使您能够控制用户可以访问哪些方法和属性,与传统的继承方式不同,后者会暴露所有内容。

如果您需要集成来自其他源的 Web 组件,请使用专业的替代方案:

AI skill available

The webforj-creating-components skill can wrap web components, JS libraries, or compositions as reusable webforJ components. After installing the webforJ AI plugin, ask your assistant:

  • "Wrap this Custom Element library as webforJ components."
  • "Compose these webforJ components into a reusable card."
  • "Integrate this plain JavaScript library as a webforJ component."

用法​

要定义一个 Composite 组件,请扩展 Composite 类并指定它所管理的组件类型。这将成为您的绑定组件,即持有您内部结构的根容器:

BasicComposite.java
public class BasicComposite extends Composite<FlexLayout> {
private final FlexLayout self = getBoundComponent();

public BasicComposite() {
// 访问绑定组件以进行配置
self.setDirection(FlexDirection.COLUMN)
.setSpacing("3px")
.add(new TextField(), new Button("Submit"));
}
}

getBoundComponent() 方法提供对您底层组件的访问,使您可以配置其属性、添加子组件并直接管理其行为。

绑定组件可以是任何 webforJ 组件 或 HTML 元素组件。对于灵活的布局,请考虑将 FlexLayout 或 Div 用作您的绑定组件。

组件扩展

永远不要直接扩展 Component 或 DwcComponent。始终使用 Composite 的组合模式来构建自定义组件。

当您需要更大的灵活性来创建和管理绑定组件时,请重写 initBoundComponent(),例如使用带参数的构造函数而不是默认的无参数构造函数。当绑定组件需要组件在其构造函数中传递而不是之后添加时,请使用此模式。

CustomFormLayout.java
public class CustomFormLayout extends Composite<FlexLayout> {
private TextField nameField;
private TextField emailField;
private Button submitButton;

@Override
protected FlexLayout initBoundComponent() {
nameField = new TextField("Name");
emailField = new TextField("Email");
submitButton = new Button("Submit");

FlexLayout layout = new FlexLayout(nameField, emailField, submitButton);
layout.setDirection(FlexDirection.COLUMN);
layout.setSpacing("10px");

return layout;
}
}

组件生命周期​

webforJ 自动处理 Composite 组件的所有生命周期管理。通过使用 getBoundComponent() 方法,大多数自定义行为可以在构造函数中处理,包括添加子组件、设置属性、基本布局设置和事件注册。

public class UserDashboard extends Composite<FlexLayout> {
private final FlexLayout self = getBoundComponent();
private TextField searchField;
private Button searchButton;
private Div resultsContainer;

public UserDashboard() {
initializeComponents();
setupLayout();
configureEvents();
}

private void initializeComponents() {
searchField = new TextField("Search users...");
searchButton = new Button("Search");
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() {
// 搜索逻辑在此
}
}

如果您有其他特定的设置或清理要求,您可能需要使用可选的生命周期钩子 onDidCreate() 和 onDidDestroy():

public class DataVisualizationPanel extends Composite<Div> {
private Interval refreshInterval;

@Override
protected void onDidCreate(Div container) {
// 初始化需要 DOM 附加的组件
refreshInterval = new Interval(5.0, event -> updateData());
refreshInterval.start();
}

@Override
protected void onDidDestroy() {
// 清理资源
if (refreshInterval != null) {
refreshInterval.stop();
}
}

private void updateData() {
// 数据更新逻辑
}
}

如果您需要在组件附加到 DOM 后执行任何操作,请使用 whenAttached() 方法:

InteractiveMap.java
public class InteractiveMap extends Composite<Div> {
public InteractiveMap() {
setupMapContainer();

whenAttached().thenAccept(component -> {
initializeMapLibrary();
loadMapData();
});
}
}

示例 Composite 组件​

以下示例演示了待办事项列表,其中每个项目都是一个 Composite 组件,包含 RadioButton、带文本的 Div 和一个 Button。

显示代码

示例:组件分组​

有时,您可能希望使用 Composite 将相关组件组合在一起,形成一个单一单元,即使重用不是主要关注点:

显示代码

Keep learning

webforJ 团队

需要帮助吗?

与 webforJ 的工程师聊聊您的项目。

Book a call

We speak EN · DE · FR · ES