我有一个JSF页面,用户可以在其中向我的数据库输入他们的汽车。该表单有三个输入字段:
- <
- 制造商/gh>
- 登记
Manufacturer
和Model
字段都是自动补全字段。为了完成Model
字段,我需要知道用户在提交表单之前在Manufacturer
字段中选择了什么值。为此,我设置了一个AJAX调用,将选中的值通知受管bean:
<p:autoComplete id="manufacturer"
minQueryLength="3"
completeMethod="#{carController.complete}"
forceSelection="true">
<p:ajax event="itemSelect"
listener="#{carController.manufacturerSelected}" />
</p:autoComplete>
在受管bean中:
public void manufacturerSelected(SelectEvent se) {
manufacturer = se.getObject().toString();
}
模型的自动完成字段和处理程序方法看起来大致相同,只是值略有不同。
为了在多个XHR请求中保留manufacturer
值,我将bean设置为ConversationScoped
,并在@PostConstruct
注释方法中开始对话:
@Named
@ConversationScoped
public class CarController implements Serializable {
@Inject
private Conversation conversation;
@PostConstruct
private void init() {
conversation.begin();
}
我所期望的是bean只为页面实例化一次,因为会话尚未结束,并保留manufacturer
字段中的值。然而,这并不成立,并且为每个XHR请求再次实例化bean,导致manufacturer
字段也变为null
。在PostConstruct
方法中设置一个断点表明它实际上正在被调用,manufacturerSelected
方法也是如此。
我怀疑这与我没有手动传播会话ID的事实有关,但是文档说这个ID应该与任何面部请求自动传播。这是真的吗?这是否意味着XHR请求不一定是面向请求?
Edit:在bean中的各个位置设置断点显示每个XHR请求都有一个新bean (conversation.getId()
不断变化),因此我显然没有传播ID的权利。如何使用ajax传播ID,以及在哪里可以使用EL获得ID ?
既然您没有真正使用会话(至少不是在您给出的示例中),为什么不使用视图作用域呢?这将完全满足您的需求,而不需要传播会话id的开销。
请注意,要使@ViewScoped工作,您必须将bean更改为JSF管理的bean(删除@Named)。这是由于Java EE 6中的设计错误/规范疏忽造成的。如果你想继续使用CDI,那么Seam 3的Java EE 6扩展可以修复这个错误。
是的。这是JSF 2和Primefaces一起不传播会话id的一个问题。您可以尝试下面的解决方法。(这是给那些因为同样的问题而最终在这里结束的人)。
<p:autoComplete id="manufacturer"
minQueryLength="3"
completeMethod="#{carController.complete}"
forceSelection="true" onchange="updateManufacturer([{name:'cid',value:'#{javax.enterprise.context.conversation.id}'}])">
</p:autoComplete>
<p:remoteCommand name="updateManufacturer" action="#{carController.manufacturerSelected}"
process="manufacturer" />