Jsf 将inputText元素动态添加到绑定的数据表中会清空其他inputText

Jsf 将inputText元素动态添加到绑定的数据表中会清空其他inputText,jsf,facelets,Jsf,Facelets,我正在设计一个表单生成器,用户可以在其中为他们的问题添加多个选项。因此,每个选项都有一个添加新选项按钮和一个删除按钮。 我想在Facelets页面中使用dataTable,并将其与托管bean中的HtmlDataTable绑定,以便动态添加/删除选项,因为我们不知道他们想要添加多少选项。 所以我所做的是,我的dataTable的值是字符串的列表。我的输入文本(选项)被添加和删除,当它们添加整个问题时,它们被正确地存储在我的数据库中。但每次按下“添加”或“删除”按钮时,我的选项都是空的,因此用户必

我正在设计一个表单生成器,用户可以在其中为他们的问题添加多个选项。因此,每个选项都有一个添加新选项按钮和一个删除按钮。 我想在Facelets页面中使用
dataTable
,并将其与托管bean中的
HtmlDataTable
绑定,以便动态添加/删除选项,因为我们不知道他们想要添加多少选项。 所以我所做的是,我的
dataTable
的值是字符串的
列表。我的输入文本(选项)被添加和删除,当它们添加整个问题时,它们被正确地存储在我的数据库中。但每次按下“添加”或“删除”按钮时,我的选项都是空的,因此用户必须再次输入它们。
我的代码有点长,所以我将为您提供它们的简化版本

在我的Facelets页面上,我有:

<h:dataTable value="#{questionMaker.selectOneOptionList}" var="option" binding="#{questionMaker.table}"> 
<h:column>                                                                                     
<h:inputText value="#{option}"/>
<h:commandLink value="remove option" action="#{questionMaker.removeRadioButtonOption}"/>                                           
</h:commandLink>
</h:column>
</h:dataTable>
这种方法存在几个(潜在)问题:

  • 为了让这个构造工作,bean必须是视图范围(不是请求范围,也不是会话范围)。在请求范围中,每个请求都会重新创建
    selectOneOptionList
    。你不想那样。在会话范围内,bean将在所有浏览器窗口/选项卡之间共享。你也不想这样

  • 绑定
    属性在视图生成期间运行。因此,如果
    {questionMaker}
    是视图作用域,那么它将由于以下原因隐式成为请求作用域

  • 作为一个不可变对象,
    字符串
    没有setter方法。
    将永远无法设置输入的值

因此,要解决您的问题,您必须:

  • 确保bean是
    @viewscope
  • 不要让
    binding
    属性指向视图范围的bean属性
  • 用一个完整的javabean替换
    String
    ,或者改为通过索引访问列表项
因此,应该这样做(假设出于某种原因,您仍然希望坚持使用
List
):


...

@ManagedBean
@视域
公开课提问者{
私人列表selectOneOptionList;
@施工后
公共void init(){
selectOneOptionList=新建ArrayList();
}
public void addRadioButtonOptions(){
添加(新字符串());
}
公共列表getSelectOneOptionList(){
返回selectOneOptionList;
}
}
另见:

听起来这是一个很棒的解决方案@Balus。我现在要测试一下。但是你能告诉我我的菜豆应该是什么样子吗?它必须扩展/实现什么吗?不,只是一个简单的
@ManagedBean
类。我更新了bean示例,以显示所需的最少代码。关于另一个例子,请参见“CRUD框架”链接。因此,我的表bean将使用一个项目列表查看CRUD示例。什么是物品?只是模型而已。在您的情况下,可能是
问题
?当在单个窗口/选项卡中打开页面时,会话范围肯定“有效”。但正如回答的那样:“在会话范围内,bean将在所有浏览器窗口/选项卡之间共享。您也不希望这样。”。因此,在多个窗口/选项卡中打开同一页,并在它们之间切换时播放。结果是不直观和混乱的!因此,这只是目的的错误范围。另请参见第一个“请参见”链接。
private HtmlDataTable table;
private List<String> selectOneOptionList;
public void addRadioButtonOption() {
    String option = new String();
    selectOneOptionList.add(option);

}
<h:dataTable value="#{questionMaker.selectOneOptionList}" binding="#{table}"> 
  <h:column>                                                                                     
    <h:inputText value="#{questionMaker.selectOneOptionList[table.rowIndex]}"/>
    ...
  </h:column>
</h:dataTable>
<h:commandButton value="add" action="#{questionMaker.addRadioButtonOption}" />
@ManagedBean
@ViewScoped
public class QuestionMaker {

    private List<String> selectOneOptionList;

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

    public void addRadioButtonOption() {
        selectOneOptionList.add(new String());
    }

    public List<String> getSelectOneOptionList() {
        return selectOneOptionList;
    }

}