我有一个启动应用程序,我正在添加一些crud屏幕。我决定使用Vaadin,在我将其部署到多节点生产环境之前,它似乎工作得很好。一旦进入prod环境,屏幕就会无缘无故地不断刷新。例如,在一个屏幕中有一个网格,当单击一行时,会弹出一个显示项目详细信息的对话框。但一旦对话框弹出,页面就会刷新多次。
这个论坛的帖子在这里https://vaadin.com/forum/thread/17586129/routerlayout-causing-page-refresh是我正在使用的相同布局的一个示例,描述了一个非常类似的问题。
我有一个扩展VerticalLayout的基础抽象类,所有的具体类都扩展了这个基础抽象类。每个混凝土类定义自己的管线并使用公共布局类。
我已经联系了gitter,瓦丁论坛,并在github中打开了一个bug,但据我所知,瓦丁没有人想回应任何事情。
以下是我使用的所有版本:Vaadin Flow版本:14 Java版本:12.0.1 12 OS版本:Mac 10.14.5浏览器版本:Fire Fox 70.0.1,Chrome 78.0.3904.97
我的实现中的代码片段:主视图
@Slf4j
@RoutePrefix("v1/crud")
@Theme(value = Material.class, variant = Material.DARK)
public class MainView extends Div implements RouterLayout {
private H1 h1 = new H1("Vaadin Crud UI");
private HorizontalLayout header = new HorizontalLayout(h1);
private Div content = new Div();
private ApplicationContext context;
@Inject
public MainView(ApplicationContext context) {
this.context = context;
setSizeFull();
h1.setWidthFull();
content.setWidthFull();
header.setWidthFull();
header.setAlignItems(FlexComponent.Alignment.CENTER);
VerticalLayout navigationBar = new VerticalLayout();
navigationBar.setWidth("25%");
navigationBar.add(createNavigationButton("Home", VaadinIcon.HOME, ReportTab.class));
navigationBar.add(createNavigationButton("Batch Search", VaadinIcon.SEARCH, BatchSearchTab.class));
... a bunch more buttons
HorizontalLayout layout = new HorizontalLayout(navigationBar, content);
layout.setWidthFull();
VerticalLayout page = new VerticalLayout(header, layout);
page.setWidthFull();
add(page);
}
@Override
public void showRouterLayoutContent(HasElement hasElement) {
if (hasElement != null) {
Element newElement = hasElement.getElement();
if (newElement != null) {
content.removeAll();
content.getElement().appendChild(newElement);
}
}
}
private Button createNavigationButton(String caption, VaadinIcon icon, Class<? extends BaseEditor> editor) {
Button button = new Button(caption, icon.create());
button.addClickListener(event -> UI.getCurrent().navigate(editor));
button.addThemeVariants(ButtonVariant.MATERIAL_CONTAINED);
button.getStyle().set("background-color", "#00819D");
button.setWidthFull();
return button;
}
}
基础组件:
@Slf4j
@Data
@SpringComponent
@UIScope
public abstract class BaseEditor<P, B> extends VerticalLayout {
private final RememberMeService rememberMe;
private final P businessProcess;
protected Binder<B> binder;
protected Dialog editDialog = new Dialog();
protected Button save = new Button("Save", VaadinIcon.CHECK.create());
protected Button close = new Button("Close", VaadinIcon.EXIT.create());
protected Button delete = new Button("Delete", VaadinIcon.TRASH.create());
protected B bean;
private ChangeHandler changeHandler;
private boolean proceed = true;
public BaseEditor(P businessProcess, RememberMeService rememberMe) {
this.rememberMe = rememberMe;
this.businessProcess = businessProcess;
save.addClickListener(e -> save());
delete.addClickListener(e -> delete());
}
public abstract void delete();
public abstract void save();
protected abstract Component getContent();
protected void edit(B e) {
bean = e;
editDialog.open();
getBinder().setBean(e);
}
protected void initEditorPanel(Component... components) {
HorizontalLayout actions = new HorizontalLayout(save, close, delete);
VerticalLayout data = new VerticalLayout(components);
data.add(actions);
editDialog.removeAll();
editDialog.add(data);
getBinder().bindInstanceFields(this);
close.addClickListener(e -> editDialog.close());
}
public interface ChangeHandler {
void onChange();
}
void setChangeHandler(ChangeHandler h) {
changeHandler = h;
}
void errorDialog(String message) {
final Button close = new Button("Close", VaadinIcon.CLOSE.create());
H3 h3 = new H3(message);
final Dialog errorDialog = new Dialog(h3, close);
errorDialog.open();
close.addClickListener(e -> errorDialog.close());
}
BaseEditor filter(Predicate<B> predicate) {
Objects.requireNonNull(predicate);
proceed = predicate.test(bean);
return this;
}
void buttonConsumer(Consumer<B> consumer) {
if (!proceed) {
proceed = true;
return;
}
try {
consumer.accept(bean);
} catch (Exception e) {
errorDialog(e.getMessage());
} finally {
editDialog.close();
getChangeHandler().onChange();
}
}
void either(Consumer<B> whenTrue, Consumer<B> whenFalse) {
try {
if (proceed) {
whenTrue.accept(bean);
} else {
whenFalse.accept(bean);
}
} catch (Exception e) {
errorDialog(e.getMessage());
} finally {
proceed = true;
editDialog.close();
getChangeHandler().onChange();
}
}
}
混凝土构件:
@Slf4j
@Route(value = "search/batch", layout = MainView.class)
public class BatchSearchTab extends BaseEditor<BatchService, Batch> {
private TextField searchField1;
private TextField searchField2;
public BatchSearchTab(BatchService businessProcess, RememberMeService rememberMe) {
super(businessProcess, rememberMe);
binder = new Binder<>(Batch.class);
save.setIcon(VaadinIcon.REPLY.create());
save.setText("Replay");
delete.setIcon(VaadinIcon.CLOSE.create());
delete.setText("Cancel");
getContent();
}
@Override
public void delete() {
buttonConsumer(b -> getBusinessProcess().cancelBatch(b.getBatchId(), b.getUserAgent()));
}
@Override
public void save() {
filter(b -> b.isReplayable()).buttonConsumer(b -> getBusinessProcess().buildAndSendFile((getBean())));
}
@Override
public void edit(Batch batch) {
HorizontalLayout actions = new HorizontalLayout();
H2 h2 = new H2();
if (batch.isReplayable()) {
h2.setText("Would you like to replay the following.");
actions.add(save, delete, close);
} else {
h2.setText("This record is not eligible for replay.");
actions.add(close);
}
Label batchId = new Label("Correlation Id: " + batch.getBatchId());
Label txnCount = new Label("Transaction Count: " + batch.getTotalTxns());
Label txnAmount = new Label("Total: " + batch.getTotalBatchAmount());
VerticalLayout data = new VerticalLayout(h2, batchId, txnCount, txnAmount, actions);
data.add(actions);
editDialog.removeAll();
editDialog.add(data);
close.addClickListener(e -> editDialog.close());
editDialog.open();
getBinder().setBean(batch);
}
@Override
protected Component getContent() {
final H2 h2 = new H2("Locate Batches");
searchField1 = new TextField("Batch Code");
searchField2 = new TextField("User Agent");
searchField2.addKeyPressListener(Key.ENTER, e -> keyPressListener());
Button searchBtn = new Button("Search", VaadinIcon.SEARCH.create());
HorizontalLayout search = new HorizontalLayout(searchField1, searchField2);
searchBtn.addClickListener(e -> {
search(searchField1.getValue(), searchField2.getValue());
});
add(h2, search, searchBtn);
return this;
}
private void search(String code, String userAgent) {
log.info("Searching {} and {}", code, userAgent);
List<Batch> batches =
getBusinessProcess().getBatchesForUserAgent(code, userAgent, 60);
log.info("Found {} batches", batches.size());
if (batches.size() > 0) {
buildGrid(batches, "BatchId", "totalTxns", "totalBatchAmount", "status");
} else {
errorDialog("No Records found for criteria");
}
}
private void keyPressListener() {
String code = StringUtils.isNotBlank(searchField1.getValue()) ? searchField1.getValue() : null;
if (StringUtils.isNotBlank(searchField2.getValue())) {
search(code, searchField2.getValue());
}
}
private void buildGrid(Collection<Batch> records, String... columns) {
Component result;
if (records.size() == 0) {
result = new Label("NO REPORT DATA AVAILABLE.");
} else {
final Grid<Batch> grid = new Grid<>(Batch.class);
grid.setHeightByRows(records.size() < 10);
grid.setColumns(columns);
grid.setItems(records);
grid.setWidthFull();
grid.asSingleSelect().addValueChangeListener(l -> Optional.ofNullable(l.getValue()).ifPresent(this::edit));
result = grid;
}
if (getComponentCount() < 3) {
add(result);
} else {
replace(getComponentAt(2), result);
}
}
private void loadData(String code, String userAgent) {
if (StringUtils.isNotBlank(code)) {
search(null, userAgent);
} else {
search(code, userAgent);
}
}
}
免责声明:一些进一步的事实调查通过IRC进行
这个问题的答案与OP在循环加载ballancer之后运行应用程序的多个实例有关。客户端随机访问服务器,因此没有会话在那里运行。
解决方案是有一个共享会话存储,理想情况下在现有会话上有load ballancer dispatch,这样“热”后端服务器就会受到影响。
Fancybox破坏Swiper。在没有可见CSS和DOM更改的情况下添加偏移量。要在jsbin(https://output.jsbin.com/jiqucacete)上复制此问题,您需要: 1)按下swiper幻灯片图像2)转到fancybox图库弹出的下一个图像3)关闭图库,在swiper中将有幻灯片变化 它是如何工作的?为什么没有可见的CSS、DOM更改?如何修复?
我使用的是Appium版本1.4.0(draco)和Xcode版本6.4。我无法让刷卡功能在我的自动测试中工作。iOS的模拟器设备是iPad air。任何有用的帖子将不胜感激。
【参数】 子链刷新的参数在subchainbase.sol中定义。参数列表如下: 1.刷新周期Round数值:定义子链经过多少区块后刷新。假如子链有100个节点,每个节点依次产生block,定义Round数为5,则每过500block 刷新一次。 2.当前刷新id 索引:指定下次刷新的id 在Nodelist中 的索引值 3.刷新过期数值expiration:指定的id在block [0, 2*e
使用android软键盘输入文本并使用键盘下方可用的键手动关闭后,应用程序页面不会刷新。键盘所在的位置显示一个黑色空间。 我尝试了windowSoftInputMode的各种可用选项,但没有解决这个问题。遗憾的是,adjustPan没有表现出预期的行为。当windowSoftInputMode设置为adjustPan时,键盘隐藏文本字段。 隐藏软键盘后如何使页面刷新以消除此问题?
} 用于显示股票的HTML页面:
这是我使用SpringBoot的第一天,我试图理解体系结构,因此我开始构建一个hello world应用程序: 在我的pom.xml中,在maven-shade-plugin下,我将mainClass声明如下: 文件目标是src/main/java/com/demo/helloworld.java,该文件中的代码是: 我错过了什么?