将inputText元素动态添加到绑定的dataTable会清空其他inputTexts

时间:2012-10-02 13:07:18

标签: jsf facelets

我正在设计一个表单制作者,用户可以在其中为他们的问题添加多个选项。因此,每个选项都有一个新的选项按钮和一个删除按钮。 我想在我的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);

}

1 个答案:

答案 0 :(得分:2)

这种方法存在几个(潜在的)问题:

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

  • binding属性在视图构建期间运行。因此,如果#{questionMaker}是视图作用域,那么由于JSF issue 790,它会隐式请求作用域。

  • 作为一个不可变对象,String没有setter方法。 <h:inputText value="#{option}"/>永远无法设置输入的值。

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

  • 确保您的bean为@ViewScoped
  • 不要让binding属性指向视图范围的bean属性。
  • 用完全值得的javabean替换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;
    }

}

另见: