使用 f:ajax 时 JSF 不触发 bean setter

Posted

技术标签:

【中文标题】使用 f:ajax 时 JSF 不触发 bean setter【英文标题】:JSF not firing bean setters when using f:ajax 【发布时间】:2012-11-16 05:32:26 【问题描述】:

这是我之前关于页面组件条件渲染的post 的更新。我现在可以使用 f:ajax 标记根据选定的用户输入有条件地在页面上呈现不同的组件。问题在于,当我单击命令按钮时,使用 ajax 有条件地呈现的输入不会在提交时被读取。我猜这是因为当我添加新组件时整个页面没有重新呈现,并且提交按钮看不到它们,即使它们在那里。这是我的表单页面的片段(它包含在 h:form 标记中):

            <h:outputLabel for="selectPersonType" value="Select Type: "/>
            <h:selectOneMenu id="selectPersonType" value="#addPersonBean.personType" label="Person Type" required="true">
                <f:selectItem itemValue=""/>
                <f:selectItems value="#listBean.personTypes" />
                <f:ajax render="results"/>
            </h:selectOneMenu>
            <h:message for="selectPersonType" style="color: red"/>
        </h:panelGrid>

        <h:panelGroup id="results">
            
            <h:panelGroup rendered="#addPersonBean.personType == 'STUDENT'">
                <h:outputLabel for="selectSchoolType" value="School Type: " />
                <h:selectOneMenu id="selectSchoolType" value="#addPersonBean.schoolType">
                    <f:selectItems value="#listBean.schoolTypes" />
                    <f:ajax execute="selectSchoolType"/>
                </h:selectOneMenu>
            </h:panelGroup>
            
            <h:panelGroup rendered="#addPersonBean.personType == 'PATIENT'">
                <h:outputLabel for="smoker" value="Smoker? " />
                <h:selectBooleanCheckbox id="smoker" value="#addPersonBean.smoker">
                    <f:ajax execute="smoker"/>
                </h:selectBooleanCheckbox>
  
            </h:panelGroup>
        </h:panelGroup>

        <h:commandButton value="Add Person" action="#addPersonBean.action"/>

这里的问题是,当我单击命令按钮时,没有设置 ID 为“selectSchoolType”和“吸烟者”值的组件,因为它们是在页面加载后使用 selectPersonType 选择菜单有条件地呈现的。有没有办法在组件的值更改而不是单击提交按钮时触发组件(因此,在我单击提交之前应该处理它们的值)。如您所见,我尝试使用 f:ajax 和附加到相关组件的执行属性,但它似乎不起作用。 (我相信这些组件的默认事件是 valueChange,所以没有将它们添加到 f:ajax 标记中,但我尝试过 'change' 和 'valueChange')。

【问题讨论】:

你能写下一个简化的场景,它不像你预期的那样工作吗?例如:我点击了这个......但没有完成...... 但它被简化了。我单击 commandButton,ID 为“selectSchoolType”和“smoker”的组件的值不会发送到支持 bean 设置器。即使它们被选中/选中,它们也会作为 null 发送。 加个&lt;f:ajax execute="@form"/&gt;怎么样,像这样&lt;h:commandButton value="Add Person" action="#addPersonBean.action"&gt;&lt;f:ajax execute="@form"/&gt;&lt;/h:commandButton&gt; 【参考方案1】:

你所有的&lt;f:ajax&gt; 东西都在一个条件渲染的组件中。在处理表单提交期间,当rendered 属性后面的条件评估为false 时,此构造将失败。当#addPersonBean 在请求范围内并且在(后)构造期间没有预初始化rendered 属性后面的条件时,或者当它以错误的方式在getter/setter 中执行业务逻辑时,就会发生这种情况。

#addPersonBean 放在视图范围内并确保您没有在getter/setter 中执行业务逻辑应该可以解决此问题。

另见:

commandButton/commandLink/ajax action/listener method not invoked or input value not updated - 第 5 点适用于您 How to choose the right bean scope?

【讨论】:

太棒了!!我只是像你说的那样将 bean 范围从请求更改为查看,它起作用了!您在提供的两个链接中提供的信息非常有帮助,谢谢。你碰巧写过 JSF 什么的吗?)

以上是关于使用 f:ajax 时 JSF 不触发 bean setter的主要内容,如果未能解决你的问题,请参考以下文章

JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用

JSF f:ajax 监听器 vs commandButton 动作

在页面加载时调用 JSF 托管 bean 操作

为什么使用f:ajax(JSF)更新后,我的Materialize可折叠菜单不起作用?

JSF 页面元素无法从具有动作属性的支持 bean 触发方法。(JSF2.0 + primefaces)

在会话作用域的JSF支持bean中观察CDI事件