Вопрос

У меня есть команда, который вызывает функцию, чтобы загрузить файл (стандартные вещи, такие как InputStream, BufferedOutputStream ...) После загрузки успеха в конце функции я изменяю некоторые значения текущего объекта и упорствуйте в базе данных. Все эти работы правильно. Теперь, когда выполняется файл загрузки, содержимое страницы не обновляется. Я должен ударить обновление для меня, чтобы увидеть обновленный контент. Пожалуйста помоги. Ниже приведены основную структуру моего кода

document: Управляемый боб
getDrawings(): Метод Вернуть список рисунков (класс объекта)
CheckedOutBy: атрибут объекта Drawing

<p:dataTable id="drawing_table" value="#{document.drawings}" var="item" >                            
    <p:column>
        <f:facet name="header">
              <h:outputText value="CheckedOutBy"/>
        </f:facet>
        <h:outputText value="#{item.checkedOutBy}"/>
        ...
</p:dataTable>
<p:commandButton ajax="false" action="#{document.Download}" value="Download" />

Внутри моего управляемого боба

public void Download(){
    Drawing drawing = getCurrentDrawing();
    //Download drawing
    drawing.setCheckedOutBy("Some Text");
    sBean.merge(drawing);  //Update "Some Text" into CheckedOutBy field
}
Это было полезно?

Решение

Вы бы в основном хотели бы позволить клиенту два Запросы. Один извлекает загрузку и другое, чтобы обновить новую страницу. Они не могут быть сделаны в одном HTTP-запросе. Поскольку загрузка должна быть проведена синхронно, и нет никакого способа подключить к загрузке с клиентской стороны, нет чистого JSF / JS / AJAX способов обновить компонент при завершении загрузки.

Ваша лучшая JSF-ставка с помощью выпуклых <p:poll>

<h:outputText id="checkedOutBy" value="#{item.checkedOutBy}"/>
...
<p:poll id="poll" interval="5" update="checkedOutBy" />

или <p:push>

<p:push onpublish="javaScriptFunctionWhichUpdatesCheckedOutBy" />  

Опрос легко, но я могу представить, что добавляет ненужные накладные расходы. Вы не можете начать его, используя стандартные компоненты JSF / PROMEFACES, когда запускается синхронная загрузка. Но вы можете остановить его, чтобы позволить ему сделать самопроверка на rendered атрибут. Толкание технически лучшее решение, но более сложное, чтобы начать. Вымазы объясняют его использование, однако, в главе 6 руководства пользователя.

Другие советы

Ну, я решил пойти с ответом / рекомендацией Balusc / Рекомендацию выше, и решил поделиться своим кодом здесь для людей, которые могут остановиться здесь, «позже». FYI, мои детали окружающей среды ниже:

Tomee 1.6.0 Snapshot (Tomcat 7.0.39), Pightfaces 3.5 (Primefaces Push), Atmopps 1.0.13 Снимок (1.0.12 - последняя стабильная версия)

Прежде всего, я использую P: FileDownload с P: CommandLink.

<p:commandLink value="Download" ajax="false"
               actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}">
    <p:fileDownload value="#{driverWorksheet.file}"/>
</p:commandLink>

Поскольку у меня выше у меня XHTML, и поскольку P: FileDownload не позволяет выполнять oncomplete = "queyjavascript ()" для выполнения, я решил использовать primefaces push для нажимания сообщения клиенту, чтобы вызвать JavaScript, необходимый для разблокировки пользовательского интерфейса, потому что UI Был заблокирован всякий раз, когда я нажимаю в CommandLink для скачивания файла, а в течение многих месяцев я не знал, как решить это.

Поскольку я уже использую Primfaces Push, мне пришлось настроить следующее на стороне клиента:

.js файл; Содержит метод, который обрабатывает сообщения, нажатые с сервера на клиента

function handlePushedMessage(msg) {
    /* refer to primefaces.js, growl widget,
     * search for: show, renderMessage, e.detail
     * 
     * sample msg below:
     * 
     * {"data":{"summary":"","detail":"displayLoadingImage(false)","severity":"Info","rendered":false}}
     */
    if (msg.detail.indexOf("displayLoadingImage(false)") != -1) {
        displayLoadingImage(false);
    }
    else {
        msg.severity = 'info';
        growl.show([msg]);
    }
}

index.xhtml; Содержит p: сокет компонента (prushs push); Я рекомендую все следующее, если вы реализуете примечание FaceSmessage Prush Push

<h:outputScript library="primefaces" name="push/push.js" target="head" />
<p:growl id="pushedNotifications" for="socketForNotifications"
         widgetVar="growl" globalOnly="false"
         life="30000" showDetail="true" showSummary="true" escape="false"/>
<p:socket id="socketForNotifications" onMessage="handlePushedMessage"
          widgetVar="socket"
          channel="/#{pf_usersController.userPushChannelId}" />

Месяцы (или, может быть, год или так) назад, я обнаружил, что необходимо добавить следующее в CommandLink, который оборачивает P: FileDownload, которая будет обновлять файл / поток на сервере, поэтому вы можете нажать на файл столько раз, сколько Вам нужно и загрузить файл еще раз и снова, не обновляя страницу через ключ F5 / Обновить на клавиатуре (или похожее на мобильном устройстве)

actionListener="#{pf_ordersController.refreshDriverWorksheetsToDownload()}"

Этот метод бобов ссылается, всякий раз, когда enduser нажимает кнопку CommandLink, чтобы загрузить файл, поэтому это было идеальное место для «нажать» сообщение с сервера на клиента, для запуска JavaScript на клиенте, чтобы разблокировать пользовательский интерфейс.

Ниже приведены методы бобов в моем приложении, которые выполняют работу. :)

pf_orderscontroller.refreshdriverworksheetToDownload ()

public String refreshDriverWorksheetsToDownload() {
    String returnValue = prepareDriverWorksheetPrompt("download", false);
    usersController.pushNotificationToUser("displayLoadingImage(false)");
    return returnValue;
}

userscontroller.pushnotificationToususter (); Я должен был добавить это, сегодня вечером.

public void pushNotificationToUser(String notification) {
    applicationScopeBean.pushNotificationToUser(notification, user);
}

applicationscopebean.pushnotificationToususter (); Это уже существовало, без изменений в этот метод.

public void pushNotificationToUser(String msg, Users userPushingMessage) {
    for (SessionInfo session : sessions) {
        if (userPushingMessage != null &&
            session.getUser().getUserName().equals(userPushingMessage.getUserName()) &&
            session.getUser().getLastLoginDt().equals(userPushingMessage.getLastLoginDt())) {
            PushContext pushContext = PushContextFactory.getDefault().getPushContext();
            pushContext.push("/" + session.getPushChannelId(),
                             new FacesMessage(FacesMessage.SEVERITY_INFO, "", msg));
            break;
        }
    }
}

Вы могли бы использовать update атрибут p:commandButton Компонент, чтобы повторно сделать область, которую вы намереваетесь обновить после загрузки, в этом случае ваша «Drawing_table».

<p:commandButton update="drawing_table" action="#{document.Download}" value="Download" />

Так как Balusc. Ответил, мы не можем получить ответ дважды от одного запроса.

Чтобы обновить страницу после загрузки, лучше использовать следующий сценарий Java в ссылке загрузки (p:commandbutton) метка onclick.

Пример:

<p:commandButton ajax="false" icon="ui-icon-arrowstop-1-s" onclick="setTimeout('location.reload();', 1000);" action="#{managedBean.downloadMethod}" />

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top