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

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

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


person raffael    schedule 05.12.2013    source источник
comment
Проблема со скрытой кнопкой в ​​том, что она не работает на устройствах с iOS. Я бы предпочел использовать MenuBar и MenuItem, но Vaadin пока не поддерживает их — см. Github issue # 4057. И предлагаемый обходной путь при использовании MenuBar и MenuItem приведет к использованию скрытых кнопок...   -  person bingele28    schedule 14.03.2018


Ответы (2)


Я сам нашел решение. На самом деле два. В первом используется устаревший метод 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);
}
}

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

person raffael    schedule 05.12.2013
comment
Открывают ли эти решения файл на новой вкладке или в новом всплывающем окне? - person Nhat Nam NGUYEN; 09.06.2015
comment
вы можете управлять поведением, установив параметр windowName в Page.open(), см.: vaadin.com/api/7.4.7/com/vaadin/server/ - person raffael; 09.06.2015
comment
Конечно, но браузер «Сохранить как файл» не открывается. - person Nhat Nam NGUYEN; 09.06.2015
comment
возможно, браузер блокирует всплывающее окно - person raffael; 09.06.2015
comment
Как вы определяете, куда загружается файл? - person jhugo; 26.10.2015

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

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

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

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

    .InvisibleButton {
        display: none;
    }
    
  2. Когда пользователь щелкает элемент меню: расширьте 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();");
      }
    });
    
person Community    schedule 04.06.2015
comment
имхо, это не работает, потому что каждый щелчок по одному и тому же элементу будет добавлять расширение для invisibleButton, и поэтому он будет запускать одну загрузку в первый раз, но две загрузки во второй... и так далее.. - person Lorenzo Sciuto; 09.06.2015
comment
Лоренцо: Перед вызовом extend() вам нужно удалить все старые расширения кнопки. - person Nhat Nam NGUYEN; 09.06.2015