我正在设计一个表单制作者,用户可以在其中为他们的问题添加多个选项。因此,每个选项都有一个新的选项按钮和一个删除按钮。
我想在我的Facelets页面中使用dataTable
并将其与我的托管bean中的HtmlDataTable
绑定,以便动态添加/删除选项,因为我们不知道他们想要多少选项加。
所以我所做的是我的dataTable
的值是一个List
的字符串。添加和删除我的输入文本(选项),当他们添加整个问题时,它们会正确存储在我的数据库中。但每次按下添加或删除按钮时,我的选项都是空的,因此用户必须再次输入。
我的代码有点冗长,所以我会为你提供它们的简化版本。
在我的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中,上面的变量是:
private HtmlDataTable table;
private List<String> selectOneOptionList;
当然,他们也有吸气剂和二传手。
这是我的添加方法:
public void addRadioButtonOption() {
String option = new String();
selectOneOptionList.add(option);
}
答案 0 :(得分:2)
这种方法存在几个(潜在的)问题:
为了使这个构造起作用,bean必须是视图范围的(不是请求,也不是会话范围)。在请求范围中,将在每个请求上重新创建selectOneOptionList
。你不想拥有它。在会话范围中,bean将在所有浏览器窗口/选项卡之间共享。你也不想拥有它。
binding
属性在视图构建期间运行。因此,如果#{questionMaker}
是视图作用域,那么由于JSF issue 790,它会隐式请求作用域。
作为一个不可变对象,String
没有setter方法。 <h:inputText value="#{option}"/>
永远无法设置输入的值。
因此,要解决您的问题,您必须:
@ViewScoped
。binding
属性指向视图范围的bean属性。String
,或者用索引访问列表项。所以,这应该做(假设你仍然想因某种原因坚持List<String>
):
<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;
}
}