Question

J'ai un bouton de commande qui appellera une fonction pour télécharger un fichier (des étoffes standard comme InputStream, BufferedOutputStream ...) Après le téléchargement succès, à la fin de la fonction, je modifier certaines valeurs de l'objet courant et persister dans base de données. Tous ces éléments fonctionnent correctement. Maintenant, lorsque le fichier est le téléchargement terminé, le contenu de la page n'est pas mis à jour. Je dois actualisez pour moi de voir le contenu mis à jour. aide s'il vous plaît. Voici la structure de base de mon code

document: Managed Bean
getDrawings(): méthode retourne une liste de dessin (classe d'entité)
CheckedOutBy: attribut de l'entité 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" />

Dans mon Bean Managed

public void Download(){
    Drawing drawing = getCurrentDrawing();
    //Download drawing
    drawing.setCheckedOutBy("Some Text");
    sBean.merge(drawing);  //Update "Some Text" into CheckedOutBy field
}
Était-ce utile?

La solution

Vous souhaitez essentiellement comme de laisser le feu client deux demandes . Un pour récupérer le téléchargement et d'autres pour actualiser la nouvelle page. Ils ne peuvent pas se faire dans une requête HTTP. Étant donné que les besoins de téléchargement à prendre en synchronisme et il n'y a aucun moyen de accrocher complète du téléchargement à partir du côté client sur, il n'y a pas JSF propre / moyens JS / Ajax pour mettre à jour un composant sur complète du téléchargement.

Votre meilleur JSF-bet avec l'aide de PrimeFaces est <p:poll>

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

ou <p:push>

<p:push onpublish="javaScriptFunctionWhichUpdatesCheckedOutBy" />  

Polling est facile, mais je peux imaginer que cela ajoute une surcharge inutile. Vous ne pouvez pas commencer à l'aide de composants standard JSF / PrimeFaces lors du démarrage du téléchargement synchrone. Mais vous pouvez arrêter de le laisser faire un auto-contrôle sur l'attribut rendered. Pousser est techniquement la meilleure solution, mais plus difficile pour commencer avec. PrimeFaces explique son utilisation mais bien dans le chapitre 6 du Guide de l'utilisateur.

Autres conseils

Eh bien, je décide d'aller avec la réponse / recommandation de BalusC ci-dessus, et a décidé de partager mon code ici pour les gens qui peuvent arrêter par ici, « plus tard ». Pour votre information, les détails de mon environnement sont ci-dessous:

tomee 1.6.0 INSTANTANÉ (Tomcat 7.0.39), PrimeFaces 3.5 (PrimeFaces Push), l'atmosphère 1.0.13 instantané (1.0.12 est la dernière version stable)

Tout d'abord, j'utilise p: fileDownload avec p. CommandLink

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

Depuis que j'ai le xhtml ci-dessus, et comme p: fileDownload ne permet pas onComplete = "someJavaScript ()" à exécuter, je décide d'utiliser PrimeFaces Push to pousser un message au client, pour déclencher le javascript nécessaire pour débloquer l'interface utilisateur , parce que l'interface utilisateur a été bloqué à chaque fois que je clique sur le commandLink au fichier de téléchargement, et pendant plusieurs mois, je ne savais pas comment résoudre ce problème.

Depuis que je suis déjà à l'aide PrimeFaces Push, je devais modifier ce qui suit sur le côté client:

.js fichier; contient méthode qui gère les messages poussés du serveur vers le client

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 contient: un composant femelle (PrimeFaces push); Je recommande tout ce qui suit, si vous implémentez exemple FacesMessage de PrimeFaces Appuyez sur

<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}" />

mois (ou peut-être un an ou si) il y a, je l'ai trouvé nécessaire d'ajouter ce qui suit à la commandLink qui enveloppe p: fileDownload qui rafraîchira le fichier / flux sur le serveur, vous pouvez cliquer sur le fichier en tant que autant de fois que vous avez besoin et télécharger le fichier encore et encore sans rafraîchir la page via F5 / Actualiser la clé sur le clavier (ou similaire sur l'appareil mobile)

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

Cette méthode de haricot est référencé chaque fois enduser clique sur le commandLink, dans le fichier de téléchargement, cela a donc été parfait endroit pour « pousser » un message du serveur au client, de déclencher le javascript sur le client, à l'interface utilisateur de débloquage.

Voici les méthodes de haricots dans mon application qui fait le travail. :)

pf_ordersController.refreshDriverWorksheetsToDownload ()

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

usersController.pushNotificationToUser (); je devais ajouter celui-ci, ce soir.

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

applicationScopeBean.pushNotificationToUser (); cela existait déjà, aucun changement à cette méthode.

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;
        }
    }
}

Vous pouvez utiliser l'attribut update du composant p:commandButton de réengendrer la zone que vous avez l'intention de rafraîchir après le téléchargement, dans ce cas, votre « drawing_table ».

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

Balusc répondu, nous ne pouvons pas obtenir une réponse deux fois de une demande unique.

Pour rafraîchir une page après le téléchargement, utilisez le mieux java script suivant dans le lien de téléchargement (de p:commandbutton) tag onclick .

Exemple:

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

cela rafraîchira automatiquement la page après 1 seconde, en même temps dire avant actualisation, vous obtiendrez le fichier de téléchargement, en fonction de votre temps de réponse de téléchargement, augmenter les secondes dans ce script. secondes ne devrait pas moins que le temps de réponse de téléchargement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top