Vaadin FileDownload 需要点击按钮两次才能下载

Vaadin FileDownload requires the button be clicked twice to download

我正在遵循 Vaadin 示例代码,但是当我这样做时,我需要第二次单击才能开始文件下载。下面是我的代码:

final StreamResource streamResource = new StreamResource(
        () -> {
            return new ByteArrayInputStream("hello world".getBytes());
        }, document.getName() + ".txt");

FileDownloader fileDownloader = new FileDownloader(streamResource);
fileDownloader.extend(getDownloadButton());

创建按钮的代码没有什么特别之处,但按照此处评论中的要求,它是:

Button downloadButton = new Button("Download");

虽然我不喜欢这个解决方案,但它确实有效。它与下载的工作方式和浏览器的一些限制有关。我确信有更好的解决方案,但现在我用 Javascript 模拟第一次点击。如果有人能找到正确答案,请 post 它,我会更改所选答案,否则这是我找到的唯一解决方案(post 在 Vaadin 论坛中编辑)。

streamResource = createStreamResource();
downloadButton createDownloadButton();
downloadButton.setId("DownloadButtonID");

if(fileDownloader == null)
{
    fileDownloader = new FileDownloader(streamResource);
    fileDownloader.extend(downloadButton);
    // Javascript click so that it works without a second click
    Page.getCurrent().getJavaScript().execute(
           "document.getElementById('DownloadButtonID').click();");
} else {
    fileDownloader.setFileDownloadResource(streamResource);
}

下载文件二次点击需求的解决方案是按钮的监听器。就像我的情况一样,我有按钮的点击侦听器,其中 FileDownloader 扩展了按钮。但它应该没有监听器,因为 FileDownloader 有自己的机制来处理监听器操作。

在这里,第一个按钮点击由 clickListener 处理,只有在点击事件通过 FileDownloader 时,fileDownloader 扩展了下载按钮,该按钮拥有下载文件的所有功能,并且此功能仅发生。所以下次点击会通过 FileDownloader,因为现在它会扩展按钮。

public static Button getDownloadButton(String fileName, String fileAsString, String caption) {
    // caption
    Button dwnButton = new Button(caption, VaadinIcons.DOWNLOAD);
    dwnButton.addClickListener(listener -> {
        StreamResource resource = createResource(fileName, fileAsString);
        FileDownloader fileDownloader = new FileDownloader(resource);
        fileDownloader.extend(dwnButton);
    });
    return dwnButton;
} 

这里,fileDownloader 已经扩展了按钮,它拥有所有的流资源。所以在第一次点击时只调用下载。

public static Button getDownloadButton(String fileName, String fileAsString, String caption) {
    // caption
    Button dwnButton = new Button(caption, VaadinIcons.DOWNLOAD);
    StreamResource resource = createResource(fileName, fileAsString);
    FileDownloader fileDownloader = new FileDownloader(resource);
    fileDownloader.extend(dwnButton);
    return dwnButton;

}

对我来说,我在构造函数中使用虚拟资源初始化了 FileDownloader:

if (fileDownloader == null) {
    fileDownloader = new FileDownloader(streamResourceDummy);
    fileDownloader.extend(button);
}

并在按钮事件侦听器中设置实际资源:

buttonClick(ClickEvent event){
if (fileDownloader != null) {
// close previous stream
((StreamResource) fileDownloader.getFileDownloadResource()).getStreamSource().getStream().close();
    fileDownloader.setFileDownloadResource(streamResource);
}

}

而且它有效:))。我正在使用 Vaadin 8.