【问题标题】:How to update Vaadin Grid after push?推送后如何更新 Vaadin Grid?
【发布时间】:2015-07-03 08:27:25
【问题描述】:

在从不同的 UI 实例对网格进行更改后,我正在尝试更新 Vaadin 中的网格。

详细地说,我有两个不同的 UI 实例,UI1 和 UI2(来自两个不同浏览器的选项卡)。这些 UI 实例包含一个视图,其中包含一个由联系人对象组成的网格,这些对象具有各种属性,例如姓名、年龄、性别...

我从 UI1 向网格中添加了一个联系人,我希望 UI2 无需刷新即可立即看到更新后的网格。

要做到这一点,我知道我必须使用已经使用 Broadcaster 类设置的 Vaadin Push。我的 UI 类中有一个 receiveBroadcast() 方法,每当 View 类使用 broadcast() 方法向 UI 发送广播时,它都会更新 UI。我的部分 UI 类如下所示:

@Title("Contact Book")
@Theme("reindeer")
@Push
public class UserInterface extends UI implements BroadcastListener{    

    private Navigator navigator;

    @Override
    protected void init(VaadinRequest request){
        navigator = new Navigator(this, this);
        navigator.addView(ContactBookView.NAME, new ContactBookView());

        Broadcaster.register(this);
    }
    @Override
    public void detach(){
        Broadcaster.unregister(this);
        super.detach();
    }

    @Override
    public void receiveBroadcast(Grid grid) {
        access(()->{

            // update grid here
            Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
        });
    }
}

我的 Broadcaster 类与 this link 中的相同(我只是稍微更改了方法,以便可以将网格作为参数传递)

然后在我的 ContactBookView 类中,我在添加或更改项目后调用 Broadcaster.broadcast(grid) 方法,以便我可以在我的 UI 类的 access() 方法中以某种方式更新网格,但我尝试的任何方法似乎都不起作用。我知道推送正在工作,因为收到广播时,我可以在所有 UI 实例中看到“网格已更新”消息。

我试图删除视图并重新初始化

navigator.removeView(ContactBookView.NAME);
navigator.addView(ContactBookView.NAME, new ContactBookView());

试图完全清空网格并重新填充

grid.removeAllColumns();
grid.setContainerDataSource(container);

试图使用这种丑陋的解决方法强制网格自我更新

grid.setContainerDataSource(grid.getContainerDataSource());

尝试执行 JavaScript 查询以强制 UI 同步

JavaScript.getCurrent().execute("javascript:vaadin.forceSync();");

但这些都不起作用。也许我做错了什么?仅供参考,我的 Vaadin 版本是 7.5.0。

如果有任何反馈或建议,我将不胜感激,

谢谢。

【问题讨论】:

    标签: java vaadin vaadin7 vaadin-push


    【解决方案1】:

    我在重新初始化后重新导航到当前视图,设法解决了这个问题。最终的 UI 访问方法如下所示:

    public void receiveBroadcast() {
        access(()->{
    
            navigator.removeView(ContactBookView.NAME);
            navigator.addView(ContactBookView.NAME, new ContactBookView());
            navigator.navigateTo(ContactBookView.NAME);
            Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
        });
    

    这样,视图会在后台刷新并推送到 UI 实例,而无需进行物理刷新。

    我确信可能有更好的解决方法,这个方法看起来有点难看,但目前可以满足我的需求。但是,我仍然希望有任何不同的方法。

    【讨论】:

      【解决方案2】:

      如果您使用的是navigator.navigateTo(PortletUI.SOMEPAGE);

      在 somePageInstance 中应该首先调用enter() 方法,而你将通过导航器到达那里,所以你不能尝试在那里更新网格:o)

      PortletUI:

      public static final String SOMEPAGE = null;
      Navigator navigator;
      
      SomePage somePageInstance = null;
      
       protected void init(VaadinRequest request) {
              InitPortlet.initPortlet(this);
      
              // Create a navigator to control the views
              navigator = new Navigator(this, this);
      
             somePageInstance = new SomePage();
      
              navigator.addView(SOMEPAGE, somePageInstance);
      

      一些页面:

      public class SomePage extends SomePageDesign implements View{
      
      //or you can give there navigator from portlet through constructor probably
      Navigator navigator; 
      
      @Override
          public void enter(ViewChangeEvent event) {
               //needed for navigate to another page :)
              navigator = event.getNavigator();
              //Update grid
          }
      }
      

      希望对你有帮助:)

      【讨论】:

      • 我明白你关于“输入”方法的观点,但广播器通过单击按钮被激活,我在尝试在 UI 之间推送更新时不使用“navigatoTo”方法,所以我不能似乎明白为什么我需要在“enter”方法中更新网格,因为它只在我调用“navigateTo”方法时被调用。
      猜你喜欢
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多