富Faces和JSF/AJAX生命周期

3
我已经成功让代码实现了我的意图,但我不理解其中一个方面为什么有效。我正在运行Seam 2.2.2和Richfaces 3.3.3。
以下是xhtml页面的代码:
...
<h:form id="radiobuttontestform">

    <fieldset>           
        <h:panelGrid columns="3">

            <h:selectOneRadio layout="pageDirection" id="myRadio" value="#{actionBean.myRadioButton}">
                <f:selectItem itemLabel="First" itemValue="0" />
                <f:selectItem itemLabel="Second" itemValue="1" />
                <a4j:support event="onclick" ajaxSingle="true" process="myDropdown" reRender="myDropdown,myCount,test" />
            </h:selectOneRadio>
          <h:panelGrid columns="1" border="0">
            <h:selectOneListbox size="1" id="myDropdown" value="#{actionBean.rowCountPredefined}" disabled="#{actionBean.myRadioButton != '0'}">
                <f:selectItem itemLabel="10" itemValue="10" />
                <f:selectItem itemLabel="20" itemValue="20" />
                <f:selectItem itemLabel="30" itemValue="30" />
            </h:selectOneListbox>

            <h:inputText id="myCount" maxlength="5" value="#{actionBean.rowCountSpecified}" disabled="#{actionBean.myRadioButton != '1'}" required="true">
                <f:validateLongRange minimum="1" maximum="1000" />
                <rich:ajaxValidator event="onkeyup" for="myCount" />
            </h:inputText>
            <rich:message id="errorMessage" for="myCount" ajaxRendered="true" showDetail="false" showSummary="true">
                <f:facet name="errorMarker">ERROR:</f:facet>
            </rich:message>
       </h:panelGrid>

    </h:panelGrid>
    </fieldset>
    <h:outputLabel id="test" value="RadioValue: #{actionBean.myRadioButton}" />

    <a4j:commandButton id="show" value="Show Values in Log" action="#{actionBean.showValues}" />
    <a4j:commandButton id="done" value="Save and end conversation" action="#{actionBean.apply}" />
</h:form>
...

这个Backing Bean只是一个简单的POJO,具有三个属性的getter和setter。(myRadioButton、rowCountPredefined、rowCountSpecified)
这是我得到的结果:(正确的结果) 单选按钮示例 http://katzekat.de/Bilder/radio2.png 单选按钮示例 http://katzekat.de/Bilder/radio.png 这是我的想法:
将ajaxSingle设置为true意味着只有单选按钮会在服务器上处理。它旁边的下拉框不需要验证——它总是包含正确的值。我添加了process="myDropdown",以便将值持久化到Backing Bean中,否则当我将单选按钮切换到位置2时,下拉框会恢复其原始值。(我意识到这只是一种外观!)我使用调试器检查过了,它确实将属性设置在Backing Bean中,一切都按预期工作。
一旦单选按钮切换到位置2,就可以在文本框中输入值并进行验证。这个功能非常完美,当我将单选按钮切换回位置1时,如果该字段处于错误状态,则验证错误会被清除。这可能是因为请求作用域中仅存在错误消息。
当单选按钮处于位置2并在文本字段中输入有效值时,再次启动调试器后,当切换回位置1时,后台bean没有更新。我也预料到了这一点,因为我只告诉单选按钮和下拉列表在服务器上处理。然而,这是我不理解的部分——如果后备bean中没有保存此文本字段的值,那么这个文本字段的值会被保留在postback中。 (请参见上面的第二个链接)

如果这些图片没有消失,那么这个问题可能会更有用! :) - Lambart
他们回来了 - 正在更换主机 :-) - Heidi_DE
太好了!我在研究JSF生命周期问题时发现了你的问题。我想这个问题/答案对我帮助不大,但是这是一个写得很好的问题。顺便说一句,我发现这个超级有用的ooold页面:http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html 也许你已经找到它了,或者现在已经非常了解JSF生命周期,但是它对我帮助很大。 - Lambart
1个回答

2

提交的表单值存储在组件的应用请求值阶段中。

例如,在您的情况下,文本字段的javax.faces.component.html.HtmlInputText#decode方法调用javax.faces.component.UIInput#setSubmittedValue。由于该组件未包含在execute部分中,因此提交的值不会设置到bean中(正如您所期望的那样)。然后,inputText的渲染器重新显示(写入响应)提交的值。

当验证失败时,它的工作原理几乎相同。提交的值存储在应用请求值阶段,然后由于验证失败,提交的值没有设置到bean中(更新模型值阶段被跳过),然后重新显示提交的值。


嗨,谢谢你的回答。我原本以为apply request values阶段不会被调用ajaxSingle="true"之外的其他组件。另外,我不明白的是为什么当我删除process="myDropdown"时下拉框没有保留它的值,而文本框却保留了!作为一个实验,我在下拉框中添加了一个ajax验证器(我意识到在这种情况下它永远不会被触发),并从我的support标签中删除了process。这也保留了postback上的值。 - Heidi_DE
此外,我刚刚读到了一个消息,即rich:ajaxValidator跳过了除验证之外的所有JSF阶段!现在这一切都更加合理了 - 当我使用ajax验证器时,我设置了一个PhaseListener,并且可以看到恢复视图、应用请求值、处理验证和渲染响应都被调用了。谢谢! - Heidi_DE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接