Когда я добавляю компоненты к компоненту Ваадина (например, TabSheet
или Tree
), добавленные компоненты кэшируются. Когда пользователь щелкает вкладку (или узлы дерева), если она содержит данные db, она показывает устаревшие данные, не отражающие последнее состояние db.Убедитесь, что Vaadin загружает последние данные при нажатии на добавленные компоненты (например, TabSheet или Tree ...)
Интересно, есть ли способ обеспечить загрузку последних данных?
Я решить эту проблему, определив свой пользовательский интерфейс:
public interface Reloadable {
void reload();
}
И каждый компонент реализует этот пополняемый интерфейс, такие как:
@SpringComponent
public class TeachersView extends VerticalLayout implements Reloadable, Serializable {
@Inject
private TeacherDao teacherDao;
private final static int PAGESIZE = 10;
private MTable<Teacher> mTable = new MTable<>(Teacher.class);
@PostConstruct
public void init() {
// mTable settings skip here
reload();
addComponent(mTable);
}
@Override
public void reload() {
mTable.setBeans(new SortableLazyList<>(
sortablePagingProvider ,
() -> (int) teacherDao.count() ,
PAGESIZE
));
}
private SortableLazyList.SortablePagingProvider<Teacher> sortablePagingProvider =
(firstRow, asc, sortProperty) -> {
return teacherDao.findAll(
new PageRequest(
firstRow/PAGESIZE, PAGESIZE,
asc ? Sort.Direction.ASC : Sort.Direction.DESC,
sortProperty == null ? "id" : sortProperty
)
).getContent();
};
}
И этот вид впрыскивается UI
класса:
@SpringUI(path = "/ui")
@Theme("valo")
public class VaadinUI extends UI {
@Inject
private TeacherDao teacherDao;
@Inject
private TeachersView teachersView;
@Override
protected void init(VaadinRequest vaadinRequest) {
Panel panel = new Panel("Admin Panel");
HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
splitPanel.setSplitPosition(15, Unit.PERCENTAGE);
panel.setContent(splitPanel);
Tree tree = new Tree("Menu");
splitPanel.setFirstComponent(tree);
Label home = new Label("Home");
Map<String, Component> map = new HashMap<>();
map.put("Teachers", teachersView);
map.put("Home", home);
map.forEach((k, v) -> tree.addItem(k));
tree.addItemClickListener(event -> {
Component view = map.get(event.getItemId());
if (view instanceof Reloadable) {
((Reloadable) view).reload();
}
splitPanel.setSecondComponent(view);
});
splitPanel.setSecondComponent(home);
setContent(panel);
} // init()
}
Отметьте tree.addItemClickListener
, Я должен проверить каждый компонент, если он реализует Reloadable
, если true, вызовите его.
Это работает. Но я не знаю, соответствует ли это стандарту способом достижения этого? Я думаю, что это должен быть общий сценарий, должно быть что-то вроде встроенного интерфейса для компонентов для реализации, например onRender
(но я не могу найти его). Я что-то пропустил?
Спасибо.
Ваше решение выглядит нормально, особенно если оно работает.Мы можем думать о методе attach() в интерфейсе Component, но attach() будет вызываться только один раз, когда компонент добавляется в контейнер. –