在多标签模式下通过主菜单打开了A,B,C三个界面。这个时候不管当前标签页是否是B,如果再去点击主菜单打开B。发现B界面重新加载了。按说这个界面已经打开过了,直接选中该标签页就行了,为啥整个界面好像重新创建了,用户输入的数据,选中的行等等状态全部丢失了。这不符合默认的使用习惯吧?是要设置什么选项吗?
印象中之前提到这这个问题:( , 看一下这个属性:
cuba.web.mainTabSheetMode
和这个没关系啊,怎么设置都不对
按默认的设置就有问题,您可以稍微试一下。原来提的问题是标签页切换之后会销毁重建,但是状态都不会丢弃,现在切换标签页不会有问题。现在的问题是点主菜单发送切换标签页的时候,状态全丢,这太不友好了。
哦,是这个问题。
从源码看现在是这种行为, 不过应该可以扩展。
1 . 从 ScreenCommand
继承一个类:ExtScreenCommand,覆盖这个类的 run
方法。在这个方法中增加检测界面是否已经打开的逻辑。
2 . 扩展 MenuItemCommands
Bean,覆盖
MenuItemCommand create(FrameOwner origin, MenuItem item)
方法。 对于 screen
类型的菜单重新创建自定义的 ScreenCommand.
return new ExtScreenCommand(origin, item, item.getScreen(), item.getDescriptor(), params, properties);
先这样试试,有问题再沟通。
好的,感谢,我先试试
发现通过扩展WebScreens类,重写showFromNavigation里的逻辑即可实现。现在有个问题就是判断出screen已经在标签页中,如何调用代码让标签页选中这个界面呢?能给点思路吗?
成了
@Override
public OperationResult showFromNavigation(Screen screen) {
LaunchMode launchMode = screen.getWindow().getContext().getLaunchMode();
if (launchMode == OpenMode.NEW_TAB
|| launchMode == OpenMode.NEW_WINDOW) {
WebAppWorkArea workArea = getConfiguredWorkArea();
if (workArea.getMode() == AppWorkArea.Mode.SINGLE) {
Collection<Screen> currentBreadcrumbs = workArea.getCurrentBreadcrumbs();
if (!currentBreadcrumbs.isEmpty()) {
Iterator<Screen> iterator = currentBreadcrumbs.iterator();
OperationResult result = OperationResult.success();
// close all
while (result.getStatus() == OperationResult.Status.SUCCESS
&& iterator.hasNext()) {
Screen previousScreen = iterator.next();
result = previousScreen.close(NAVIGATION_CLOSE_ACTION);
}
if (result.getStatus() != OperationResult.Status.SUCCESS) {
// if unsaved changes dialog is shown, we can continue later
return result.compose(() -> showFromNavigation(screen));
}
}
} else {
ScreenStack sameScreen = getTabbedScreensStacks(workArea)
.filter(windowStack -> windowStack.getBreadcrumbs().size() == 1) // never close non-top active screens
.map(windowStack -> new ScreenStack( windowStack.getBreadcrumbs().iterator().next(),windowStack))
.filter(screenStack -> isAlreadyOpened(screen, screenStack.screen))
.findFirst()
.orElse(null);
//如果screen已经打开则直接选中
if (sameScreen!=null){
sameScreen.stack.select();
return OperationResult.success();
}else {
if (isMaxTabCountExceeded(screen)) {
showTooManyOpenTabsMessage();
return OperationResult.fail();
}
}
// if (!UiControllerUtils.isMultipleOpen(screen)) {
//
//
// if (sameScreen != null) {
// OperationResult result = sameScreen.close(NAVIGATION_CLOSE_ACTION);
// if (result.getStatus() != OperationResult.Status.SUCCESS) {
// // if unsaved changes dialog is shown, we can continue later
// return result.compose(() -> showFromNavigation(screen));
// }
// }
// }
}
}
return show(screen);
}
建议向官方反馈一下,默认的行为其实很怪异,一般都是打开过的界面直接切换。
1 个赞