FileDownloader和复选框,下载所选项目

时间:2015-07-21 11:40:21

标签: vaadin vaadin7

我们已经创建了一个解决方案,其中用户有一个包含文件的表,每个条目都有一个复选框。他可以根据需要选择多个,然后单击下载按钮。

我们正在使用这样的资源,它应该允许动态下载,具体取决于所选项目

private StreamResource createResource(final IndexedContainer container) {
        return new StreamResource(new StreamSource() {
            @Override
            public InputStream getStream() {

                for (Object o : container.getItemIds()) {
                    CheckBox checkbox = (CheckBox) container.getItem(o).getItemProperty(C_CHECK_BOX).getValue();
                    if (checkbox.getValue()) {
                        selectedFiles.add(o);
                    }
                }
                // do some magic to get stream of selected files


            }
        }, "download.zip");
}

问题是只有第二个和后面的点击按钮才能给出预期的结果。

事实证明,FileDownoader正在从服务器获取资源,然后它正在发送组件的当前状态。这就是为什么第一次点击会产生陈旧结果的原因。

你知道如何克服这个问题吗?是否可以强制:首先更新组件然后下载资源?

非常感谢 的Pawel

3 个答案:

答案 0 :(得分:2)

默认情况下,Vaadin中的CheckBox是非立即的,这意味着当浏览器上选中(或取消选中)复选框时,它不会向服务器发送请求。立即组件也将排队的非立即事件发送到服务器,但似乎FileDownloader不会导致将非立即复选框值发送到服务器的事件。

您唯一需要做的就是在创建时立即将复选框设置为:

checkBox.setImmediate(true);

答案 1 :(得分:0)

FileDownloader不适合您的需求。正如您可以在文档中看到的那样:

  

下载应该在用户点击时直接启动,例如一个Button,无需通过服务器端点击监听器,以避免在某些浏览器中触发安全警告。

这意味着您无法动态生成由复选框值确定的download.zip文件,因为这需要访问服务器。

您至少有2个选项。每次用户更改复选框时,都可以创建新的FileDownloader并生成新的Resource download.zip。或者您可以使用以下代码行向您添加简单的ClickListener

getUI().getPage().open(resource, "_blank", false);

相关:Vaadin - How to open BrowserWindowOpener from a SINGLE BUTTON

答案 2 :(得分:0)

还有另一种设置checkBox.setImmediate(true);的解决方案。可以在单击之前发送所有组件的当前状态,而不是发送每个复选框更改。

此解决方案基于以下答案:https://stackoverflow.com/a/30643199/1344546

您需要创建文件下载按钮并隐藏它:

Button hiddenButton = new Button();    
hiddenButton.setId(HIDDEN_ID);
hiddenButton.addStyleName("InvisibleButton");
StreamResource zipResource = createResource(container);
FileDownloader fd = new FileDownloader(zipResource);
fd.extend(hiddenButton);

为您的主题添加css规则

.InvisibleButton {
    display: none;
}

然后创建另一个按钮,第一个更新状态,然后单击隐藏按钮。

Button zipDownload = new Button("Download as ZIP file");
zipDownload.addClickListener(new Button.ClickListener() {
     @Override
     public void buttonClick(Button.ClickEvent event) {    
          Page.getCurrent().getJavaScript()
         .execute(String.format("document.getElementById('%s').click();", HIDDEN_ID));
            }
        });