Подтвердить что ты не робот

Как запустить загрузку файла в vaadin без кнопки?

Я знаю, что создать FileDownloader и просто продлить с помощью Button очень просто. Но как начать загрузку без Button?
В моей конкретной ситуации прямо сейчас у меня есть ComboBox, и файл, который я бы хотел отправить пользователю, генерируется после изменения его значения на основе ввода. Файл должен быть отправлен немедленно, не дожидаясь повторного нажатия. Это легко возможно?

Спасибо Раффаэль

4b9b3361

Ответ 1

Я нашел решение самостоятельно. На самом деле два. Первый использует устаревший метод Page.open()

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    Page.getCurrent().open(res, null, false);
}
}

В javadoc здесь упоминаются некоторые проблемы с памятью и безопасностью в качестве причины для маркировки устаревших


Во втором я пытаюсь обойти этот устаревший метод, зарегистрировав ресурс в DownloadComponent. Я был бы рад, если эксперт vaadin комментирует это решение.

public class DownloadComponent extends CustomComponent implements ValueChangeListener {
private ComboBox cb = new ComboBox();
private static final String MYKEY = "download";

public DownloadComponent() {
    cb.addValueChangeListener(this);
    cb.setNewItemsAllowed(true);
    cb.setImmediate(true);
    cb.setNullSelectionAllowed(false);
    setCompositionRoot(cb);
}

@Override
public void valueChange(ValueChangeEvent event) {
    String val = (String) event.getProperty().getValue();
    FileResource res = new FileResource(new File(val));
    setResource(MYKEY, res);
    ResourceReference rr = ResourceReference.create(res, this, MYKEY);
    Page.getCurrent().open(rr.getURL(), null);
}
}

Примечание. Я не разрешаю пользователю открывать все мои файлы на сервере, и вы должны не делать это. Это просто для демонстрации.

Ответ 2

Вот моя работа. Он работает как прелесть для меня. Надеюсь, это поможет вам.

  • Создайте кнопку и спрячьте ее с помощью Css (НЕ по коду: button.setInvisible(false))

    final Button downloadInvisibleButton = new Button();
    downloadInvisibleButton.setId("DownloadButtonId");
    downloadInvisibleButton.addStyleName("InvisibleButton");
    

    В вашей теме добавьте это правило, чтобы скрыть downloadInvisibleButton:

    .InvisibleButton {
        display: none;
    }
    
  • Когда пользователь нажимает на пункт меню: расширяйте fileDownloader до downloadInvisibleButton, затем имитируйте клик по downloadInvisibleButton по JavaScript.

    menuBar.addItem("Download", new MenuBar.Command() {
      @Override
      public void menuSelected(MenuBar.MenuItem selectedItem) {
        FileDownloader fileDownloader = new FileDownloader(...);
        fileDownloader.extend(downloadInvisibleButton);
        //Simulate the click on downloadInvisibleButton by JavaScript
        Page.getCurrent().getJavaScript()
           .execute("document.getElementById('DownloadButtonId').click();");
      }
    });