推送后如何更新Vaadin网格?

时间:2015-07-03 08:27:25

标签: java vaadin vaadin7 vaadin-push

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

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

我从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。

我很感激任何反馈或建议,

感谢。

2 个答案:

答案 0 :(得分:2)

我设法通过在重新初始化后重新导航到当前视图来解决问题。最终的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实例,而不必进行物理刷新。

我确信可能会有更好的解决方法,而且这个看起来很难看,但它目前满足了我的需求。但是,我仍然欣赏任何不同的方法。

答案 1 :(得分:1)

如果您使用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);

SomePage的:

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
    }
}

希望能帮助你:)