简体   繁体   English

推送后如何更新Vaadin Grid?

[英]How to update Vaadin Grid after push?

I'm trying to update a grid in Vaadin after a change has been made to the grid from a different UI instance. 从其他UI实例对网格进行更改后,我试图在Vaadin中更新网格。

To elaborate, I have two different UI instances, UI1 and UI2 (tabs from two different browsers). 详细地说,我有两个不同的UI实例,UI1和UI2(来自两个不同浏览器的选项卡)。 These UI instances contain a view which contains a grid consisted of Contact objects that have various properties such as name, age, gender... 这些UI实例包含一个视图,该视图包含一个由Contact对象组成的网格,这些对象具有各种属性,例如姓名,年龄,性别...

I add a Contact to the grid from UI1 and I want UI2 to see the updated grid instantly without having to refresh. 我从UI1向网格添加了一个Contact,我希望UI2立即看到更新后的网格而无需刷新。

To accomplish that, I know I have to use Vaadin Push which I already set up using a Broadcaster class. 为此,我知道我必须使用已经使用Broadcaster类设置的Vaadin Push。 I have a receiveBroadcast() method in my UI class which will update the UI whenever a View class sends a broadcast to UIs using broadcast() method. 我的UI类中有一个receiveBroadcast()方法,每当View类使用broadcast()方法向UI发送广播时,该方法都会更新UI。 Part of my UI class looks like this: 我的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);
        });
    }
}

And my Broadcaster class is as the same in this link (I just altered the methods a bit so I can pass the grid as a parameter) 我的Broadcaster类与此链接相同(我只是稍微改变了方法,以便可以将网格作为参数传递)

Then in my ContactBookView class I call Broadcaster.broadcast(grid) method after adding or changing an item, so that I can update the grid somehow in my UI class' access() method but nothing I tried seems to work. 然后,在我的ContactBookView类中,添加或更改项目后,我调用Broadcaster.broadcast(grid)方法,以便可以以某种方式在UI类的access()方法中更新网Broadcaster.broadcast(grid) ,但我尝试过的任何方法似乎都不起作用。 I know that push is working because I can see the "Grid updated" message in all UI instances when broadcast is received. 我知道推送有效,因为收到广播后,我可以在所有UI实例中看到“网格已更新”消息。

I tried to remove the view and re-initialize 我试图删除视图并重新初始化

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

Tried to completely empty the grid and refill 试图完全清空网格并重新填充

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

Tried to force the grid to update itself using this ugly workaround 试图使用此丑陋的解决方法强制网格进行自我更新

grid.setContainerDataSource(grid.getContainerDataSource());

Tried to execute a JavaScript query to force the UIs to sync 尝试执行JavaScript查询以强制UI进行同步

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

But none of these worked. 但是这些都不起作用。 Maybe I'm doing something else wrong? 也许我做错了什么? FYI my Vaadin version is 7.5.0. 仅供参考,我的Vaadin版本是7.5.0。

I'd appreciate any kind of feedback or advice, 我将不胜感激任何反馈或建议,

Thanks. 谢谢。

I managed to solve the issue by re-navigating to the current view after I reinitialized it. 重新初始化后,我设法通过重新导航到当前视图来解决此问题。 Final UI access method looks like this: 最终的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);
    });

With this, the view gets refreshed in the background and pushed to the UI instances without having to refresh physically. 这样,视图将在后台刷新并推送到UI实例,而无需进行物理刷新。

I'm sure there might be better workarounds and this one seems kind of ugly but it currently satisfies my needs. 我确信可能会有更好的解决方法,这种方法看起来很难看,但是目前可以满足我的需求。 However, I'd still appreciate any different approach. 但是,我仍然会感激任何其他方法。

If you are using navigator.navigateTo(PortletUI.SOMEPAGE); 如果您使用的是navigator.navigateTo(PortletUI.SOMEPAGE);

In somePageInstance should be called first enter() method , while you will come there via navigator, so you cant to try update grid there :o) 在somePageInstance中应该首先调用enter()方法,而您将通过导航器到达那里,因此您不能尝试在那里更新网格:o)

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

Hope that helps you :) 希望对您有帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM