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