3.5.12.3. 使用 URL 历史和导航 API
本章节包含使用 URL 历史和导航 API 的示例。
假设有 Task - 任务
实体和 TaskInfo
界面,用来展示选中任务的信息。
TaskInfo
界面控制器包含 @Route
注解,用来指定此界面的路由:
package com.company.demo.web.navigation;
import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.screen.Screen;
import com.haulmont.cuba.gui.screen.UiController;
import com.haulmont.cuba.gui.screen.UiDescriptor;
@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
public class TaskInfoScreen extends Screen {
}
然后,用户可以在浏览器的地址栏输入 http://localhost:8080/app/#main/task-info
来打开此界面:
当界面打开时,地址还包含一个状态标记。
- 状态与 URL 的映射
假设TaskInfo
界面每次展示一个任务的信息,并且能控制切换选取的任务。也许需要在 URL 中反应当前查看的任务,这样可以拷贝 URL,以便之后可以在浏览器的地址栏粘贴 URL 就能打开查看此特定任务的界面。
下面的代码实现了选中任务和 URL 的映射:package com.company.demo.web.navigation;
import com.company.demo.entity.Task;
import com.google.common.collect.ImmutableMap;
import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.UrlRouting;
import com.haulmont.cuba.gui.components.Button;
import com.haulmont.cuba.gui.components.LookupField;
import com.haulmont.cuba.gui.screen.;
import com.haulmont.cuba.web.sys.navigation.UrlIdSerializer;
import javax.inject.Inject;
@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
@LoadDataBeforeShow
public class TaskInfoScreen extends Screen {
@Inject
private LookupField<Task> taskField;
@Inject
private UrlRouting urlRouting;
@Subscribe("selectBtn")
protected void onSelectBtnClick(Button.ClickEvent event) {
Task task = taskField.getValue(); (1)
if (task == null) {
urlRouting.replaceState(this); (2)
return;
}
String serializedTaskId = UrlIdSerializer.serializeId(task.getId()); (3)
urlRouting.replaceState(this, ImmutableMap.of("task_id", serializedTaskId)); (4)
}
}
1 - 从 LookupField
获取当前任务2 - 如果没有选中任务,移除 URL 参数 3 - 使用 UrlIdSerializer
来序列化任务的 id4 - 用包含序列化任务 id 参数的新状态替换当前的 URL 状态。
结果是,当用户选中任务然后点击 *Select Task 按钮时,应用程序 URL 会变化:
- UrlParamsChangedEvent
现在实现最后一个需求:当用户输入带路由和task_id
参数的 URL 时,应用程序必须展示相应任务的界面。下面是完整的界面控制器代码。package com.company.demo.web.navigation;
import com.company.demo.entity.Task;
import com.google.common.collect.ImmutableMap;
import com.haulmont.cuba.core.global.DataManager;
import com.haulmont.cuba.gui.Route;
import com.haulmont.cuba.gui.UrlRouting;
import com.haulmont.cuba.gui.components.Button;
import com.haulmont.cuba.gui.components.LookupField;
import com.haulmont.cuba.gui.navigation.UrlParamsChangedEvent;
import com.haulmont.cuba.gui.screen.;
import com.haulmont.cuba.web.sys.navigation.UrlIdSerializer;
import javax.inject.Inject;
import java.util.UUID;
@Route("task-info")
@UiController("demo_TaskInfoScreen")
@UiDescriptor("task-info.xml")
@LoadDataBeforeShow
public class TaskInfoScreen extends Screen {
@Inject
private LookupField<Task> taskField;
@Inject
private UrlRouting urlRouting;
@Inject
private DataManager dataManager;
@Subscribe
protected void onUrlParamsChanged(UrlParamsChangedEvent event) {
String serializedTaskId = event.getParams().get("task_id"); (1)
UUID taskId = (UUID) UrlIdSerializer.deserializeId(UUID.class, serializedTaskId); (2)
taskField.setValue(dataManager.load(Task.class).id(taskId).one()); (3)
}
@Subscribe("selectBtn")
protected void onSelectBtnClick(Button.ClickEvent event) {
Task task = taskField.getValue();
if (task == null) {
urlRouting.replaceState(this);
return;
}
String serializedTaskId = UrlIdSerializer.serializeId(task.getId());
urlRouting.replaceState(this, ImmutableMap.of("task_id", serializedTaskId));
}
}
1 - 从 UrlParamsChangedEvent
获取参数值2 - 对任务 id 进行反序列化 *3 - 加载任务实例并设置到界面控件