JSF在选择OneMenu选项后更新inputText



当我从selectOneMenu中选择另一个Skin时,我想更改inputText的值。一切都很好,我的Converter从菜单中返回了正确的Object,但inputText没有更新。

<h:form>
    <h:selectOneMenu id="dropdownSkin"
        value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
        valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
        onchange="this.form.submit()" converter="SkinConverter" >
        <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
            itemValue="#{c.value}" />
    </h:selectOneMenu>

    <br />
    <h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText>
    <br />
    <h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}"></h:inputText>
    <br />
    <h:inputText id="bcolor" value="#{helloBean.currentSkin.titleBar.backgroundColorStart}"></h:inputText>
</h:form>

这是我的憨豆的样子。我调试了它,对象currentSkin设置正确。现在我需要知道如何更新文本字段的内容。

@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<ExtendedSkin> mySkins;
private List<SelectItem> mySkinsSI;
private ExtendedSkin currentSkin;
public void skinValueChanged(ValueChangeEvent e) {
    currentSkin = (ExtendedSkin) e.getNewValue();
    FacesContext.getCurrentInstance().renderResponse();
}
public List<ExtendedSkin> getMySkins() {
    mySkins = XMLParser.readExtendedSkins();
    return mySkins;
}
public List<SelectItem> getMySkinsSI() {
    mySkinsSI = new LinkedList<SelectItem>();
    for (ExtendedSkin s : getMySkins()) {
        mySkinsSI.add(new SelectItem(s, s.getTitle()));
    }
    return mySkinsSI;
}
public void setMySkinsSI(List<SelectItem> myItems) {
    this.mySkinsSI = myItems;
}
public ExtendedSkin getCurrentSkin() {
    if (currentSkin == null) {
        currentSkin = getMySkins().get(0);
    }
    return currentSkin;
}
public void setCurrentSkin(ExtendedSkin currentSkin) {
    this.currentSkin = currentSkin;
}
}

这里的问题是转换器正在填充helloBean.currentSkin对象,但<h:inputText>中与该helloBean.currentSkin绑定的值:titletextColorbackgroundColorStart将被发送到服务器,并替换converter加载的实际值。换句话说:

  • 转换器被执行并且基于所选择的值构建helloBean.currentSkin
  • <h:inputText id="name">空值被发送到服务器,并将被注入到helloBean.currentSkin.title中。其他2个<h:inputText>的行为相同
  • 视图将使用选定的helloBean.currentSkin加载,并且将加载具有空值的helloBean.currentSkin.title。其他2个<h:inputText> s的行为相同

这个问题有两种可能的解决方案:

  1. <h:inputText>移到表单之外,这样空值就不会发送到服务器。加载视图时,它将保持在转换器中加载的值。

    <h:form>
        <h:selectOneMenu id="dropdownSkin"
            value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
            valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
            onchange="this.form.submit()" converter="SkinConverter" >
            <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
                itemValue="#{c.value}" />
        </h:selectOneMenu>
    </h:form>
    <br />
    <h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText>
    <!-- rest of Facelets code... -->
    
  2. 由于您正在加载helloBean.currentSkin,同时更改dropdownlist上的选定值,因此可以在<h:selectOneMenu>中使用<f:ajax>标记组件添加ajax行为,并以更干净的方式更新字段。我会选择这个解决方案。

    <h:form>
        <!-- Note that there's no need of the onchange JavaScript function -->
        <h:selectOneMenu id="dropdownSkin"
            value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
            valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
            converter="SkinConverter" >
            <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
                itemValue="#{c.value}" />
            <f:ajax process="@this" render="name tcolor bcolor" />
        </h:selectOneMenu>
        <br />
        <h:inputText id="name" value="#{helloBean.currentSkin.title}" />
        <h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}" />
        <br />
        <h:inputText id="bcolor"
            value="#{helloBean.currentSkin.titleBar.backgroundColorStart}" />
    </h:form>
    

您可以在像这样的在线教程中了解更多关于<f:ajax>的信息。

由于您将在页面中使用ajax调用,因此应该将托管bean范围从@SessionScoped更改为@ViewScoped。更多信息请点击这里:JSF 2 中的通信

相关内容

  • 没有找到相关文章

最新更新