JSF从SelectOne菜单获取对象

JSF从SelectOne菜单获取对象,jsf,object,converter,selectonemenu,Jsf,Object,Converter,Selectonemenu,我在JSF方面又遇到了一个问题。我还在学习,非常感谢你的帮助 <h:form> <h:selectOneMenu value="#{productBean.productName}"> <f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" /> <f:ajax li

我在JSF方面又遇到了一个问题。我还在学习,非常感谢你的帮助

<h:form>
    <h:selectOneMenu value="#{productBean.productName}">
        <f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" />
        <f:ajax listener="#{productBean.valueChanged(pizza)}" render="pizzaResult" />
    </h:selectOneMenu>
    <h:commandButton value ="Dodaj do zamówienia"/>
    <h:outputText id="pizzaResult" value="#{productBean.message}" />
</h:form>
我想让它验证产品是否可用。并将其打印在outputText标记中。我认为问题出在HTML中,因为所有需要的数据都是字符串,我不能以这种方式发送产品。我应该使用转换器吗?应该是什么样子?我对转换器了解不多,ProductConverter的工作示例会让我头脑清醒。
提前感谢。

来自
侦听器属性的文档:

签名必须与public void processAjaxBehavior(javax.faces.event.AjaxBehaviorEvent)匹配抛出javax.faces.event.AbortProcessingException

因此,您需要更改
valueChanged
方法,如下所示:

public void valueChanged(AjaxBehaviorEvent ev)
{
    if(this.getIs_available() == 1)
        message = "yes";
    else
        message = "no";
}
然而,一个更干净的方法是使用一个自定义程序。

(我还有一个问题。请阅读) 我想我自己可以这样解决它:(products是一个包含products的arraylist。每个产品都有类似于字段的名称,或者可以从productBean的构造函数中的数据库中获取。我迭代了列表,寻找正确的名称,然后检查其是否可用。如果不可用,我设置了正确的消息)


public void值已更改(字符串名称)
{ 
迭代器ie=products.Iterator();
while(即hasNext())
{
产品实际杆=即下一个();
字符串prodName=actualProd.getName();
int available=actualProd.getIs_available();
if(prodName.equals(name)&&available==0)
{
System.out.println(prodName+可用);
message=“商店中没有产品,抱歉”;
打破
}
其他的
message=“”;
}
}
但我不确定这样做是否正确。你怎么想?
我想学习用JavaEE编写web应用程序,正如它们应该编写的那样。“Ok it works”-这对我来说还不够。

您不需要在侦听器中传递额外的参数,因为转换和验证的值将在bean中。所以,您可以直接调用该对象上的方法。您需要的是实现
值并将其绑定到模型类

因此,假设您的
pizza
属于
pizza
类型,您的设置如下所示

观点:

<h:form>
    <h:selectOneMenu value="#{productBean.product}" converter="#{pizzaConverter}">
        <f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" />
        <f:ajax listener="#{productBean.valueChanged}" render="pizzaResult" />
    </h:selectOneMenu>
    <h:commandButton value ="Dodaj do zamówienia"/>
    <h:outputText id="pizzaResult" value="#{productBean.message}" />
</h:form>

您需要正确地实现一个转换器。例如,关于堆栈溢出时转换器的使用,也有很多例子。

但是我需要将值传递给方法当调用侦听器时,您可以直接从bean获取值,因为它已经被更新了,但是我的属性“嵌套”在ArrayList中,并且正确的产品具有该属性。不管怎样,我需要迭代以在列表中找到正确的产品,正如您自己所说的,您需要一个转换器。有关教程,请参见。基本上,您需要在
getAsObject
方法中适应这里的逻辑。如果您有重复的产品名称,则会出现唯一的问题-如果是这种情况,最好为
itemValue
使用产品id。是的,这些名称只是暂时的,因为我尚未在Bean中为id创建字段。您不需要在此处使用参数的方法,由于您的
productName
已经是
productBean
的一个属性,该属性已由JSF设置,因此在标准方法中可用。“而且您需要正确实现一个转换器。”这对我来说是一个棘手的部分。您不需要遵循这种变通方法。这既不好又浪费资源。你应该知道如何实现这个转换器。给你举了一个例子。这真的很容易,因为您了解转换器的全部内容:)
    <h:selectOneMenu value="#{productBean.productName}">
        <f:selectItems value="#{productBean.drink}" var="drink" itemValue="#{drink.name}" itemLabel="#{drink.name}" />
        <f:ajax listener="#{productBean.valueChanged(productBean.productName)}" render="drinkResult" />
    </h:selectOneMenu>

public void valueChanged(String name)
{ 
    Iterator<Product> ie = products.iterator();
    while(ie.hasNext()) 
    {
        Product actualProd = ie.next();
        String prodName =actualProd.getName();
        int available =actualProd.getIs_available();
        if(prodName.equals(name) && available == 0)
        {
            System.out.println(prodName + available);
            message = " No rpoduct in store, sorry";
            break;
        }
        else
            message = "";
    }
}
<h:form>
    <h:selectOneMenu value="#{productBean.product}" converter="#{pizzaConverter}">
        <f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" />
        <f:ajax listener="#{productBean.valueChanged}" render="pizzaResult" />
    </h:selectOneMenu>
    <h:commandButton value ="Dodaj do zamówienia"/>
    <h:outputText id="pizzaResult" value="#{productBean.message}" />
</h:form>
@ManagedBean
@ViewScoped
public class ProductBean implements Serializable {
    private Pizza product;//getter+setter
    private String message;//getter
    public void valueChanged(AjaxBehaviorEvent abe) {
        message = ((product == null) || product.isAvailable()) ? "" : "Product temporarily unavailable";
    }
}