webentwicklung-frage-antwort-db.com.de

JSF f: event preRenderView wird durch f: ajax-Aufrufe und partielle Renderings ausgelöst, etwas anderes?

Wir haben also ein f: -Ereignis:

   <f:metadata>
    <f:event type="preRenderView" listener="#{dashboardBacking.loadProjectListFromDB}"/>
   </f:metadata>

Welche wird wie gewünscht beim ersten Laden der Seite (Rendern) ausgelöst.

Dieses preRenderView-Ereignis wird jedoch auch durch ein partielles Ajax-Seitenrendering ausgelöst, bei dem eine h: panel-Gruppe mit der ID projectListing (siehe unten) erneut gerendert wird.

<h:commandButton action="#{mrBean.addProject}" value="Create Project"
                                     title="Start a new project">
   <f:ajax render="projectListing" />
</h:commandButton>

Ich möchte nur, dass das dashboardBacking.loadProjectListFromDB für das erste Seitenrendering aufgerufen wird, aber nicht, wenn es ein Ajax-Teilrendering gibt. Gibt es ein passenderes Ereignis oder eine geeignetere Methode, die ich verwenden könnte?

25
Andrew

Eine andere Option wäre, Ihre preRenderView-Funktionalität in eine @PostConstruct-Methode einer verwalteten ViewScoped-Bean zu setzen. Diese Logik wird ausgeführt, wenn die Bean initialisiert wird, und Sie behalten für alle Ihre Ajax-Anforderungen dieselbe Instanz der Bean bei, bis Sie die Ansicht ändern.

11
Brian Leathem

Ich hatte das gleiche Bedürfnis vor nicht allzu langer Zeit. Am Ende habe ich etwas von BalusC vorgeschlagen. 

In der FacesContext-Klasse gibt es eine Methode, mit der Sie wissen können, ob Sie eine vollständige Anforderung oder eine teilweise Verarbeitung abwickeln:

FacesContext.getCurrentInstance().isPostback()

Auf diese Weise können Sie weiterhin die preRenderView-Technik verwenden und prüfen, ob es sich um ein Postback im Listener handelt. Ich fand das besonders nützlich, weil ich eine Session-Bean brauchte, da der Benutzer zu einer anderen Seite navigieren musste und zurückkam. Wenn ich View-Scope-Beans (wie oben von Brian vorgeschlagen) verwendet habe, würde ich die Informationen verlieren, die ich hatte, bevor ich wegging.

31
Andre

Eine andere Möglichkeit besteht darin, zu überprüfen, ob die Anforderung eine Ajax-Anforderung in der preRenderView-Methode ist oder nicht. Sie können das Laden auch unter Berücksichtigung anderer Faktoren durchführen, z. B. ob die Anforderung ein GET ist oder nicht und ob die Validierung fehlgeschlagen ist oder nicht (die Überprüfung der Ansichtsparameter kann auf der GET-Seite fehlschlagen).

boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET") ? true : false;
boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
boolean validationFailed = fc.isValidationFailed();
7
Ryan

Der Umgang mit dem "neuen Zeitalter" wird hier beschrieben:

http://www.coderanch.com/t/509746/JSF/Java/duplicate-call-preRenderView-event#2634752

2
Kawu

Sie könnten versuchen, den preRenderView-Ereignis-Listener an eine einzelne Komponente und nicht an die Seite anzuhängen. Wählen Sie eine Komponente, die während einer Ajax-Anforderung nicht gerendert wird.

1
Brian Leathem

Ein kleines Problem ist, dass die Ansichtsparameter nicht festgelegt wurden, wenn die @ PostConstruct-Methode aufgerufen wird. Daher musste ich sie explizit abrufen:

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("theParam");
0
Manuel Palacio

update : Eigentlich habe ich das @ PostConstruct-Ding gemacht, es ist viel sauberer.

Ich hatte heute genau das gleiche Problem mit einer Sessionbeans. Ich hatte nämlich eine Event-Listener-Methode in der Bean-Session für Beanstandungszwecke registriert, die mit preRenderView registriert wurde. Ich fand jedoch heraus, dass es auch bei einigen Ajax-Sortiervorgängen für eine PrimeFaces 3-DataTable-Komponente ausgelöst wurde. Was ich am Ende tat, war die Verwendung einer booleschen Instanzvariablen in der Bean für Bean-Sessions mit Sitzungsbereich, um sicherzustellen, dass der Rumpf der Event-Listener-Methode nur beim ersten Mal ausgeführt wurde (der Boolean fungierte als Flag). Ich bin sicher, es ist in einigen Fällen ziemlich naiv und wahrscheinlich gebrochen. Ich würde also gerne wissen, warum und wie dieser vereinfachte Ansatz scheitern könnte.