Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

java - Getters inside f:verbatim called before form submission

I have the following page:

<h:form id="gameSelectionForm">
    <h:selectOneMenu id="gameSelection">
        <f:selectItems value="#{gameBean.gameIds}" />
    </h:selectOneMenu>
    <h:commandButton id="gameSelector" value="Play" action="#{gameBean.changeGame}"  />
</h:form>

<h:panelGroup id="gameDiv">
    <f:verbatim>
        <iframe src="/levelup/resources/games/#{gameBean.gameId}/#{gameBean.htmlPage}"  width="700px" height="800px" frameborder="0"/>
    </f:verbatim>
</h:panelGroup>

When I click on the "gameSelector" button, here is the sequence of events: 1. gameBean.getGameId and gameBean.getHtmlPage are called 2. gameBean.changeGame is called 3. The page is refreshed.

My issues lies in the order of 1. and 2. The changeGame modifies a gameBean variable that is used by the getGameId and getHtmlPage. I thus want to it execute first, so that when other panels are refreshed, they contain the proper data.

Please note that this issue seems to occur only for the call within the gameDiv element (other variables are properly refreshed).

Would you have any idea as to what I could do to revert the order of 1. and 2., so that the changeGame() method is the first one called?

I am using JavaServer Faces 2.0 on Tomcat 7.0.

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As per your own answer on this topic:

I removed the f:verbatim tag, and now it works properly. I still don't understand why it has caused this behaviour though.

The <f:verbatim> was introduced in JSF 1.0 a long time back with the sole purpose to be able to include plain HTML in the JSF component tree. On JSF 1.0 (and 1.1), when the component tree get built, all the plain HTML was ignored. The page get rendered with all the plain HTML first and then the rendered HTML of JSF components thereafter. So for example

<p>Hello</p>
<h:inputText />
<p>World</p>
<h:outputText value="outputtext" />
<p>This is weird</p>

get rendered as

<p>Hello</p>
<p>World</p>
<p>This is weird</p>
<input type="text" />
outputtext    

The <f:verbatim> allowed developers to take plain HTML into the JSF component tree, so that they get rendered "in sync" as you'd expect from the coding.

<f:verbatim><p>Hello</p></f:verbatim>
<h:inputText />
<f:verbatim><p>World</p></f:verbatim>
<h:outputText value="outputtext" />
<f:verbatim><p>This is weird</p></f:verbatim>

They however get inlined during view build time, not during view render time. This is the cause of your problem, the getters get invoked during restore view phase instead of render response phase.

Since JSF 1.2, with the improved view handler, it was possible to inline plain HTML "in sync" without hassling with ugly <f:verbatim> tags. So it's not needed anymore. There are also no useful use cases for the tag anymore, expect of possibly some premature performance optimizations, but still then, you should not use it in combination with dynamic data as obtained by Expression Language.

Related questions:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...