我有一个JSF页面,用户可以将他们的汽车输入我的数据库。表单有三个输入字段:
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请求不一定面临请求?
编辑:在bean的各个位置设置断点表明每个XHR请求都有一个新的bean(conversation.getId()
不断变化)所以我显然没有正确传播ID。如何使用p:ajax传播ID?我在哪里可以用EL获取它?
答案 0 :(得分:1)
由于您并未真正使用对话(至少在您提供的示例中没有),为什么不使用视图范围?这将完全符合您的要求,而无需传播会话ID。
请注意,要使@ViewScoped起作用,您必须将bean更改为JSF托管bean(删除@Named)。这是由于Java EE 6中的设计错误/规范疏忽。如果您想继续使用CDI,那么可以使用Seam 3中的Java EE 6扩展来修复此错误。
答案 1 :(得分:0)
烨。这是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" />