2011-08-27 42 views
2

我有一个JSF页面,用户可以在其中输入他们的车到我的数据库。形式有三个输入字段:对话范围意外行为

  • 厂商
  • 模型
  • 登记

ManufacturerModel字段都是自动完成的字段。为了完成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应该自动传播任何faces请求。这实际上是否正确,这是否意味着XHR请求不一定是面对请求?

编辑:在豆的不同位置设置断点透露,每个XHR请求有一个新的bean(conversation.getId()不断变化),所以我显然不传播正确的ID。如何用p:ajax传播ID,我可以在哪里用EL获得它?

+0

虽然对话可能不是这里的方法,但您可以通过例如firebug或burpproxy调试实际的ajax请求,以查看真正发送的内容。 –

回答

1

由于您没有真正使用对话(至少在您提供的示例中没有),为什么不使用视图范围呢?这将完全符合你的要求,而无需传播对话ID的开销。

请注意,要使@ViewScoped正常工作,必须将bean更改为JSF托管bean(删除@Named)。这是由于Java EE 6中的设计bug/spec监督造成的。如果您想继续使用CDI,那么可以使用Seam 3提供的Java EE 6扩展来修复此错误。

+0

哎唷,这很重要。我阅读了组件绑定并最终使用了,而不是将输入字段绑定到托管bean中的字符串值,将其绑定到HtmlInputText并对其执行getValue(),这似乎起作用。不管怎么说,还是要谢谢你! – Laurens

+0

这不是一个规范监督。 JSF在CDI之前完成。它目前不适用于Seam 3(Seam-Faces)。关于它的一个有趣的线索和它的一个替代方案是例如在http://forum.primefaces.org/viewtopic.php?f=3&t=7585 –

+0

是的,JSF早些时候完成了,但Java EE 6整体上不应该只是将各个规范捆绑在一起,而是要确保它们一起工作并不冲突。另外,由于JSF较早完成,CDI有时间以某种方式集成@ViewScoped。 –

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" />