0

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

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

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

为了实现这一点,我知道我必须使用我已经使用 Broadcaster 类设置的 Vaadin Push。我的 UI 类中有一个receiveBroadcast()方法,每当 View 类使用方法向 UI 发送广播时,它都会更新 UI broadcast()。我的 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 类在这个链接中是一样的(我只是稍微改变了方法,所以我可以将网格作为参数传递)

然后在我的 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。

我将不胜感激任何形式的反馈或建议,

谢谢。

4

2 回答 2

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 实例,而无需物理刷新。

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

于 2015-07-03T11:37:19.703 回答
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);

某页:

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

希望对你有帮助:)

于 2015-07-03T09:26:57.127 回答