0

我创建了一个基于 PrimeFaces 组件的复合组件,该组件用作多行文本组件。文本被添加到输入中,单击“添加”按钮,该文本被添加到菜单中。菜单中的项目是提交的值。这工作正常,直到我将其设置为复合组件。然后,最初的“添加”单击不会添加值。随后的点击工作正常。据我所知,直到第二次单击才创建 ViewState。我认为这是问题所在。难道我做错了什么?它是一个错误吗?这是代码:

复合组件:

    <cc:interface>
        <cc:attribute name="value" type="java.util.Collection" />
    </cc:interface>
    <cc:implementation>
        <p:inputText value="#{multiTextBean.text}" id="txtInput" />
        <p:commandButton value="Add" action="#{multiTextBean.add}"
            update="menu txtInput" />
        <p:commandButton value="Clear"
            action="#{multiTextBean.clear}" update="menu txtInput" />
        <p:selectManyMenu id="menu"
            value="#{multiTextBean.removes}">
            <f:selectItems id="items"
                value="#{multiTextBean.items}" />
        </p:selectManyMenu>
        <p:commandButton value="Remove"
            action="#{multiTextBean.remove}" update="menu" />
    </cc:implementation>

组件的支持类:

package util;
import java.io.IOException;
import java.util.Set;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.convert.ConverterException;

import org.primefaces.component.selectmanymenu.SelectManyMenu;


public class multitext extends UIInput implements NamingContainer {

public String getFamily(){
    return "javax.faces.NamingContainer";
}

@SuppressWarnings("unchecked")
@Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue)
        throws ConverterException {
    SelectManyMenu menu = (SelectManyMenu) findComponent("menu");
    UISelectItems items = (UISelectItems) menu.findComponent("items");
    Set<String> localItems = (Set<String>) items.getValue();
    return localItems;
}

@Override
public Object getSubmittedValue() {
    return this;
}

@Override
public void encodeBegin(FacesContext context) throws IOException {
    super.encodeBegin(context);
}       
 }

复合组件引用的 Bean

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class MultiTextBean {
private String text;
private Set<String> items;
private List<String> removes;

@PostConstruct
public void init(){
    items = new HashSet<String>();
    removes = new ArrayList<String>();
}

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

public Set<String> getItems() {
    return items;
}

public List<String> getRemoves() {
    return removes;
}

public void setRemoves(List<String> removes) {
    this.removes = removes;
}

public void add(){
    if(!text.isEmpty())
    {items.add(text);}
    text = null;
}

public void clear(){
    items.removeAll(items);
    text = null;
}

public void remove(){
    items.removeAll(removes);
}
 }

该组件如下所示: 在此处输入图像描述

使用此测试页面上的组件:

 <!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:mt="http://java.sun.com/jsf/composite/util"
xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Insert title here</title>
</h:head>
<h:body>
    <ui:debug hotkey="x"/>
    <form>
    <mt:multitext value="#{backingBean.submittedValues}"/>
    <p:commandButton value="Submit" action="Submit" update="@all"     process="@all"/>
    #{backingBean.submittedValues}
    </form>
</h:body>
 </html>
4

1 回答 1

1

为了在 JSF 中调用 (ajax) 动作,您需要一个<h:form>而不是<form>.

相应地修复它:

<h:form>
    ...
</h:form>

也可以看看:

于 2012-09-20T18:18:31.407 回答