spring-boot - 将新记录添加到数据库时更新 vaadin 网格
问题描述
我想将元素添加到数据库中的表中并使用新数据更新网格(可能我应该直接在 UI 上将记录添加到表中,但无论如何)。
我的grid
组件看起来像这样
@SpringComponent
public class PlayersGrid extends Grid<Player> {
@PostConstruct
public void afterInit() {
addColumn(Player::getId).setHeader("ID");
addColumn(Player::getName).setHeader("Name");
addColumn(Player::getCharacterClass).setHeader("Class");
addColumn(Player::getLevel).setHeader("Level");
}
public class GridContentObserver implements ContentObserver {
@Override
public void refreshContent() {
PlayersGrid.this.getDataProvider().refreshAll();
}
}
}
我players
通过看起来像这样的表单添加
@SpringComponent
public class CharacterCreationForm extends FormLayout {
private static final Logger LOGGER = LoggerFactory.getLogger(CharacterCreationForm.class);
private List<ContentObserver> boundObservers = new ArrayList<>();
private TextField name;
private TextField characterClass;
private TextField level;
@Autowired
private PlayerRepository repository;
@PostConstruct
public void create() {
name = new TextField();
characterClass = new TextField();
level = new TextField();
addFormItem(name, "Name");
addFormItem(characterClass, "Class");
addFormItem(level, "Level");
Binder<Player> binder = new Binder<>(Player.class);
binder
.forField(level)
.withConverter(new StringToIntegerConverter(0, ""))
.bind(Player::getLevel, Player::setLevel);
binder.bindInstanceFields(this);
Button button = new Button("Save");
button.addClickListener(buttonClickEvent -> {
try {
Player newPlayer = new Player();
binder.writeBean(newPlayer);
LOGGER.info("Attempt to write object: {}", newPlayer);
repository.save(newPlayer);
// notify observers
boundObservers.forEach(ContentObserver::refreshContent);
} catch (ValidationException e) {
e.printStackTrace();
}
});
add(button);
}
public void addObserver(ContentObserver observer) {
boundObservers.add(observer);
}
}
我在应用程序中的主视图如下所示
public MainView(PlayerRepository repository, PlayersGrid grid, CharacterCreationForm form) {
form.addObserver(grid.new GridContentObserver());
form.setWidth("30%");
// find the way to set items in the component
grid.setItems(repository.findAll());
HorizontalLayout horizontalLayout = new HorizontalLayout();
horizontalLayout.add(form);
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.add(grid, form);
verticalLayout.setHeight("100%");
add(verticalLayout);
setClassName("main-layout");
}
启动时,我将所有存储的玩家都放在网格中。但是当我使用表单保存新记录时,它会在数据库中添加新记录,但不会更新网格。
怎么了?
解决方案
尝试以下更改,我认为这些更改会使代码更清晰并解决 ContentObserver 的问题
(没有运行代码,所以我不确定编译问题!)
更改 1:PlayersGrid 实现 ContentObserver 而不是内部类
@SpringComponent
public class PlayersGrid extends Grid<Player> implements ContentObserver {
@PostConstruct
public void afterInit() {
addColumn(Player::getId).setHeader("ID");
addColumn(Player::getName).setHeader("Name");
addColumn(Player::getCharacterClass).setHeader("Class");
addColumn(Player::getLevel).setHeader("Level");
}
@Override
public void refreshContent() {
this.getDataProvider().refreshAll();
}
}
更改 2:boundObservers.forEach
@SpringComponent
public class CharacterCreationForm extends FormLayout {
private static final Logger LOGGER =
LoggerFactory.getLogger(CharacterCreationForm.class);
private List<ContentObserver> boundObservers = new ArrayList<>();
private TextField name;
private TextField characterClass;
private TextField level;
@Autowired
private PlayerRepository repository;
@PostConstruct
public void create() {
name = new TextField();
characterClass = new TextField();
level = new TextField();
addFormItem(name, "Name");
addFormItem(characterClass, "Class");
addFormItem(level, "Level");
Binder<Player> binder = new Binder<>(Player.class);
binder
.forField(level)
.withConverter(new StringToIntegerConverter(0, ""))
.bind(Player::getLevel, Player::setLevel);
binder.bindInstanceFields(this);
Button button = new Button("Save");
button.addClickListener(buttonClickEvent -> {
try {
Player newPlayer = new Player();
binder.writeBean(newPlayer);
LOGGER.info("Attempt to write object: {}", newPlayer);
repository.save(newPlayer);
// notify observers
// updated
boundObservers.forEach( observer -> observer.refreshContent() );
} catch (ValidationException e) {
e.printStackTrace();
}
});
add(button);
}
public void addObserver(ContentObserver observer) {
boundObservers.add(observer);
}
}
变化3:grid现在也是ContentObserver,所以更容易管理和理解。
public MainView(PlayerRepository repository, PlayersGrid grid, CharacterCreationForm form) {
// updated
form.addObserver(grid);
form.setWidth("30%");
// find the way to set items in the component
grid.setItems(repository.findAll());
HorizontalLayout horizontalLayout = new HorizontalLayout();
horizontalLayout.add(form);
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.add(grid, form);
verticalLayout.setHeight("100%");
add(verticalLayout);
setClassName("main-layout");
}
推荐阅读
- regex - 拆分字符串并在数组中获取分隔符
- facebook - Ios - Facebook 登录 - 应用程序连接中的 Facebook 浏览器无法正常工作
- r - Rmd to PDF 编译错误:Package geometry \paperwidth (0.0pt) too short
- mysql - 使用 MS Access 加快将数据从 Oracle 11 移动到 MySQL
- python-2.7 - python pygogo抛出错误,没有名为builtins的模块
- r - R中的嵌套函数和内存使用
- node.js - npm 5.8.0:错误!使用 ng new 时
- javascript - 如何使用 Powershell 迭代 csv 文件
- java - 我收到 exception-org.apache.catalina.core.ApplicationDispatcher.invoke 抛出异常 java.lang.IllegalStateException
- java - Apache POI Powerpoint,找不到 XMLSlideShow.createChart()