Загрузка с именем файла по умолчанию с указанием даты и времени пользовательского события в приложении Vaadin Flow - PullRequest
1 голос
/ 17 марта 2020

В моем Vaadin Flow веб-приложении (версия 14 или более поздняя) я хочу предоставить своему пользователю ссылку, которая загрузит для него файл данных. Имя файла по умолчанию для загрузки должно быть определено в тот момент, когда пользователь начинает загрузку.

Мне известен виджет Anchor в Vaadin Flow. При Anchor именем загруженного файла по умолчанию будет имя ресурса, указанное в URL-адресе ссылки. К сожалению, это определяется, когда страница загружается, а не позже, когда пользователь нажимает на ссылку. Таким образом, этот подход не соответствует моей потребности обозначить загрузку датой и временем, зафиксированным в момент, когда пользователь инициирует загрузку.

String when = Instant.now().toString().replace( "-" , "" ).replace( ":" , "" ); // Use "basic" version of standard ISO 8601 format for date-time.
StreamResource streamResource = new StreamResource( "rows_" + when + ".txt" , ( ) -> this.makeContent() );
Anchor anchor = new Anchor( streamResource , "Download generated data" );

screenshot of Anchor widget showing a link whose URL is frozen in time with an old date-time text value

Возможно, решением было бы использование виджета Button вместо Anchor. Использование кнопки для динамически создаваемого контента показано в руководстве на странице Advanced Topics > Dynami c Content . К сожалению, пример загружает ресурс на странице, а не выполняет загрузку для пользователя.

➥ Можно ли использовать Button в Vaadin Flow для инициации загрузки?

➥ есть какой-то другой подход к инициированию загрузки с помощью URL-адреса, определенного, когда пользователь инициирует загрузку, а не при загрузке страницы?

Ответы [ 2 ]

2 голосов
/ 18 марта 2020

Можно ли использовать кнопку в Vaadin Flow для запуска загрузки?

В некотором роде, но для этого требуется некоторая реализация на стороне клиента. В каталоге есть надстройка File Download Wrapper , которая делает это. Можно обернуть, например, Button. Однако я думаю, что это не решит вашу проблему полностью. Я подозреваю, что установка имени файла в событии щелчка не применяется (это слишком поздно). Но я думаю, что в эту надстройку можно добавить функцию обратного вызова провайдера имен файлов.

1 голос
/ 18 марта 2020

Рассмотрим этот HACK, который имитирует щелчок по динамически добавленному Anchor на стороне клиента:

    private void downloadWorkaround(Component anyComponent, int delay) {
        Anchor hiddenDownloadLink = new Anchor(createStreamResource(), "Workaround");
        hiddenDownloadLink.setId("ExportLinkWorkaround_" + System.currentTimeMillis());
        hiddenDownloadLink.getElement().setAttribute("style", "display: none");
        var parent = anyComponent.getParent().orElseThrow();
        var parenthc = (HasComponents) parent;
        for (Component c : parent.getChildren().collect(Collectors.toList())) {
            if (c.getId().orElse("").startsWith("ExportLinkWorkaround_")) {
                // clean up old download link
                parenthc.remove(c);
            }
        }
        parenthc.add(hiddenDownloadLink);
        UI.getCurrent().getPage().executeJs("setTimeout(function(){" + // delay as workaround for bug when dialog open before
                "document.getElementById('" + hiddenDownloadLink.getId().orElseThrow() + "').click();"
                + "}, " + delay + ");"
        );
    }

Вызов метода при событии нажатия кнопки или что-то в этом роде. Иногда требуется delay. Для меня задержка была необходима, чтобы начать загрузку из модального диалогового окна с кнопкой OK, которая также закрывала диалог. Но, возможно, вам это даже не нужно.

Мне не повезло с надстройкой для загрузки файлов, упомянутой Tatu для моего конкретного c варианта использования: я хотел показать диалог при некоторых обстоятельствах раньше предоставление загрузки пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...