首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当单击添加的组件(如TabSheet或Tree .)时,确保Vaadin加载最新数据

当单击添加的组件(如TabSheet或Tree .)时,确保Vaadin加载最新数据
EN

Stack Overflow用户
提问于 2016-03-10 05:56:55
回答 1查看 560关注 0票数 0

当我将组件添加到Vaadin的组件(如TabSheetTree)时,添加的组件将被缓存。当用户单击选项卡(或树节点)时,如果它包含db数据,它将显示陈旧的数据,而不是反映最新的db状态。

我想知道是否有办法确保加载最新的数据?

我通过定义自定义接口来解决这个问题:

代码语言:javascript
复制
public interface Reloadable {
  void reload();
}

每个组件都实现了这个可重加载的接口,例如:

代码语言:javascript
复制
@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类中:

代码语言:javascript
复制
@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,如果为真,则调用它。

起作用了。但我不知道这是否是标准的实现这一目标的方式?我认为这应该是一个常见的场景,应该有类似于内置接口的组件来实现,比如onRender (但我找不到)。我错过什么了吗?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-10 11:40:14

首先,我将建议您可能已经看到的关于Spring & Vaadin的本教程,但是我将在几个地方引用它,我认为它是Vaadin & Spring集成的一个好起点。

第二,出于好奇,你为什么要用树来构建菜单?

在提供的示例中,您似乎在对某些视图特性(已经是以Vaadin提供 )之间的导航进行建模,并且由于您使用的是春天,所以Vaadin 春天 & 弹簧靴扩展使在视图之间定义和导航变得非常容易。然后,您可以在各自的enter()方法中为每个视图定义一些特定的行为。我使用Vaadin仪表板演示作为对以下更改的灵感:

代码语言:javascript
复制
@SpringView(name = TeachersView.NAME)
public class TeachersView extends VerticalLayout implements View {
    public static final String NAME = "Teachers";

    private Label title = new Label("Teachers view");

    @PostConstruct
    void init() {
        addComponent(title);
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        // recreate or reload stuff here
        title.setValue("Teachers view reloaded @ " + new Date());
    }
}
代码语言:javascript
复制
@SpringView(name = HomeView.NAME)
public class HomeView extends VerticalLayout implements View {
    public static final String NAME = "";

    @PostConstruct
    void init() {
        addComponent(new Label("Home"));
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        // meh, nothing special to do here
    }
}
代码语言:javascript
复制
public class SpringVaadinUI extends UI {

    @Autowired
    private SpringViewProvider viewProvider;

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        addStyleName(ValoTheme.UI_WITH_MENU);
        Panel panel = new Panel("Admin Panel");

        HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
        splitPanel.setSplitPosition(15, Unit.PERCENTAGE);
        panel.setContent(splitPanel);

        VerticalLayout navigationBar = new VerticalLayout();
        navigationBar.setPrimaryStyleName(ValoTheme.MENU_ROOT);
        navigationBar.addComponent(createNavigationButton("Home", FontAwesome.HOME, HomeView.NAME));
        navigationBar.addComponent(createNavigationButton("Teachers", FontAwesome.GROUP, TeachersView.NAME));
        splitPanel.setFirstComponent(navigationBar);

        CssLayout navigationDisplay = new CssLayout();
        splitPanel.setSecondComponent(navigationDisplay);

        Navigator navigator = new Navigator(this, navigationDisplay);
        navigator.addProvider(viewProvider);

        setContent(panel);
    }

    private Button createNavigationButton(String caption, FontAwesome icon, final String viewName) {
        Button button = new Button(caption, icon);
        button.setPrimaryStyleName(ValoTheme.MENU_ITEM);
        button.addStyleName(ValoTheme.BUTTON_SMALL);
        button.addStyleName(ValoTheme.BUTTON_BORDERLESS);
        button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName));
        return button;
    }
}

其结果类似于:

如果由于某种原因不能或不想使用导航器,那么您的解决方案看起来很好。尽管如此,无论您选择使用哪种解决方案,您都应该知道默认情况下 Spring创建了单身汉。除了一些UI之外,您可能应该将组件更改为原型,这样每次都会得到一个新实例。否则,所有用户在访问应用程序时都会得到相同的实例,我认为您不希望发生这种情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35908702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档