Routing and Composites
到目前为止,本教程只有一个单页应用程序。这一步将改变这一点。
您将把在处理数据中创建的 UI 移动到自己的页面,并创建另一个页面以添加新客户。
然后,您将连接这些页面,以便应用能够通过应用这些概念在它们之间导航:
- 路由
- 组合组件
ColumnsLayout组件
完成此步骤将创建一个版本的 3-routing-and-composites。
运行应用
在开发应用程序时,您可以使用 3-routing-and-composites 作为比较。要查看应用程序的运行效果:
-
导航到包含
pom.xml文件的顶级目录;如果您正在按照 GitHub 上的版本进行操作,则该目录为3-routing-and-composites。 -
使用以下 Maven 命令在本地运行 Spring Boot 应用:
mvn
运行应用程序会自动在 http://localhost:8080 打开一个新浏览器。
可路由应用
之前,您的应用程序只有一个功能:显示现有客户数据的表格。
在这一阶段,您的应用程序还将能够通过添加新客户来修改客户数据。
将显示和修改的用户界面分开对于长远的维护和测试是有益的,因此您将这个功能添加为一个单独的页面。
您将使您的应用程序可路由,以便 webforJ 可以单独访问和加载这两个 UI。
可路由应用会基于 URL 渲染用户界面。注释继承 App 类的类时使用 @Routify 启用路由,packages 元素告知 webforJ 哪些包包含 UI 组件。
当您将 @Routify 注解添加到 Application 时,请移除 run() 方法。您将把该方法中的组件移动到您在 com.webforj.tutorial.views 包中创建的类中。您更新后的 Application.java 文件应如下所示:
@SpringBootApplication
@BundleEntry("css/card.css")
@AppTheme("system")
// 添加了 @Routify 注解
@Routify(packages = "com.webforj.tutorial.views")
@AppProfile(name = "CustomerApplication", shortName = "CustomerApplication")
public class Application extends App {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// 移除了重写的 App.run() 方法
}
将 @BundleEntry 注解保留在 Application 中,会将 CSS 文件添加到应用级前端包中,因此样式在路由视图之间保持可用。
创建路由
添加 @Routify 注解使您的应用程序可路由。一旦它可路由,您的应用程序将查看 com.webforj.tutorial.views 包中的路由。
您需要为您的 UI 创建路由,并指定它们的 路由类型。路由类型决定如何将 UI 内容映射到 URL。
第一个路由类型是 View。这种类型的路由直接映射到应用中的特定 URL 段。表格的 UI 和新客户表单的 UI 都将是 View 路由。
第二个路由类型是 Layout,它包含在多个页面上显示的 UI,如页眉或侧边栏。布局路由不会对 URL 做出贡献,但会包装子视图。
要指定类的路由类型,请将路由类型附加到类名的末尾作为后缀。
例如,MainView 是一个 View 路由类型。
为了将应用程序的两个功能分开,您的应用需要将 UI 映射到两个唯一的 View 路由:一个用于表格,另一个用于客户表单。在 /src/main/java/com/webforj/tutorial/views 中,创建两个带 View 后缀的类:
MainView:此视图将具有先前在Application类中的Table。FormView:此视图将具有用于添加新客户的表单。
将 URL 映射到组件
您的应用程序可以路由并知道要查找两个 View 路由,MainView 和 FormView,但它没有特定的 URL 来加载它们。通过在视图类上使用 @Route 注解,您可以告诉 webforJ 在给定的 URL 段中在哪里加载它。
例如,在视图中使用 @Route("about") 可以将类本地映射到 http://localhost:8080/about。
顾名思义,MainView 是您希望在应用程序运行时最初加载的类。要实现这一点,添加一个将 MainView 映射到应用程序根 URL 的 @Route 注解:
@Route("/")
public class MainView {
public MainView() {
}
}
对于 FormView,将视图映射到用户转到 http://localhost:8080/customer 时加载:
@Route("customer")
public class FormView {
public FormView() {
}
}
如果您没有明确为 @Route 注解赋值,则 URL 段为类名小写,并去掉 View 后缀。
MainView会映射到/mainFormView会映射到/form
共享特性
除了都是视图路由外,MainView 和 FormView 还具有其他共享特性。其中一些特性,如使用 Composite 组件,是使用 WebforJ 应用程序的基本要求,而其他特性则使管理应用程序更容易。
使用 Composite 组件
当应用程序是单页时,您将组件存储在 Frame 中。
展望未来,随着应用程序具有多个视图,您需要将这些 UI 组件包装在 Composite 组件 中。
Composite 组件是可重用组件的包装器。
要创建 Composite 组件,请扩展 Composite 类,并指定作为类基础的绑定组件,例如,Composite<FlexLayout>。
本教程使用 Div 元素作为绑定组件,但它们可以是任何组件,例如 FlexLayout 或 AppLayout。使用 getBoundComponent() 方法,您可以引用绑定组件并访问其方法。这让您能够设置大小,添加 CSS 类名,添加希望显示在 Composite 组件中的组件,以及访问特定于组件的方法。
对于 MainView 和 FormView,请将 Composite 与 Div 作为绑定组件进行扩展。然后,引用该绑定组件以便稍后可以添加 UI。两个视图应如下结构所示:
// 将 Composite 扩展为绑定组件
public class MainView extends Composite<Div> {
// 访问绑定组件
private Div self = getBoundComponent();
// 创建一个组件 UI
private Button submit = new Button("Submit");
public MainView() {
// 将 UI 组件添加到绑定组件
self.add(submit);
}
}
设置框架标题
当用户在浏览器中打开多个选项卡时,唯一的框架标题可以帮助他们快速识别他们打开的应用程序的哪个部分。
@FrameTitle 注解定义了在浏览器的标题或页面选项卡中显示的内容。对于两个视图,使用 @FrameTitle 注解添加框架标题:
- MainView
- FormView
@Route("/")
@FrameTitle("客户表格")
public class MainView extends Composite<Div> {
private Div self = getBoundComponent();
public MainView(CustomerService customerService) {
}
}
@Route("customer")
@FrameTitle("客户表单")
public class FormView extends Composite<Div> {
private Div self = getBoundComponent();
public FormView(CustomerService customerService) {
}
}
共享 CSS
通过在 MainView 和 FormView 中可引用的绑定组件,您可以使用 CSS 对其进行样式。
您可以使用第一步中的 CSS,创建基本应用,为两个视图提供相同的 UI 容器样式。
将 CSS 类名 card 添加到每个视图中的绑定组件:
- MainView
- FormView
@Route("/")
@FrameTitle("客户表格")
public class MainView extends Composite<Div> {
private Div self = getBoundComponent();
public MainView() {
self.addClassName("card");
}
}
@Route("customer")
@FrameTitle("客户表单")
public class FormView extends Composite<Div> {
private Div self = getBoundComponent();
public FormView() {
self.addClassName("card");
}
}
使用 CustomerService
视图的最后一个共享特性是使用 CustomerService 类。
MainView 中的 Table 显示每位客户,而 FormView 添加新客户。由于这两个视图都与客户数据交互,因此它们需要访问应用程序的业务逻辑。
视图通过在处理数据中创建的 Spring 服务 CustomerService 获得访问权限。
要在每个视图中使用 Spring 服务,请将 CustomerService 作为构造函数参数:
- MainView
- FormView
@Route("/")
@FrameTitle("客户表格")
public class MainView extends Composite<Div> {
private Div self = getBoundComponent();
public MainView(CustomerService customerService) {
this.customerService = customerService;
self.addClassName("card");
}
}
@Route("customer")
@FrameTitle("客户表单")
public class FormView extends Composite<Div> {
private Div self = getBoundComponent();
public FormView(CustomerService customerService) {
this.customerService = customerService;
self.addClassName("card");
}
}