【发布时间】:2012-01-08 09:23:29
【问题描述】:
我有一个要显示的问题嵌套列表。最初,我显示 1 级问题,然后根据用户对其父问题的回答显示子问题。所有问题都有一个单选按钮,有些问题有一个输入框,用于在用户选择“是”时显示附加信息
这是我的带有嵌套数据表的 JSF 代码。请注意,为了简化论坛上的问题,我已经删除了这些问题的格式,因此如果您将此代码复制到自己的环境中并运行代码,这些可能看起来“不漂亮”:
<h:dataTable id="questionTable" var="q" value="#{generalQuestionBean2.questions.questions}">
<h:column><h:panelGroup id="questionGrp">
#{q.question} <h:selectOneRadio value="#{q.answer}">
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
<f:ajax event="valueChange" execute="@form"
render="questionGrp"
listener="#{generalQuestionBean2.reset}"/>
</h:selectOneRadio> <h:inputText value="#{q.addnInfo}"
rendered="#{q.answer eq '1' and q.field ne 'otherCov'}"></h:inputText>
<h:panelGroup id="questionGrpSubs" rendered="#{q.addnQuestions ne null and q.answer eq '1'}">
<h:dataTable id="subQuestionTable" var="subq" value="#{q.addnQuestions}">
<h:column><h:panelGroup id="subQuestionGrp">
->#{subq.question} <h:selectOneRadio id="answer" value="#{subq.answer}">
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
<f:ajax event="valueChange" execute="@form"
render="subQuestionGrp"
listener="#{generalQuestionBean2.reset}"/>
</h:selectOneRadio><h:inputText value="#{subq.addnInfo}"
rendered="#{subq.answer eq '1' and subq.field ne 'voluntaryComp' and subq.field ne 'uslh'}"></h:inputText>
<h:panelGroup id="questionGrpSubs2" rendered="#{subq.addnQuestions ne null and subq.answer eq '1'}">
<h:dataTable id="sub2QuestionTable" var="sub2q" value="#{subq.addnQuestions}">
<h:column><h:panelGroup id="sub2QuestionGrp">
-->#{sub2q.question} <h:selectOneRadio id="answer" value="#{sub2q.answer}">
<f:selectItem itemValue="1" itemLabel="Yes"/>
<f:selectItem itemValue="0" itemLabel="No"/>
<f:ajax event="valueChange" execute="@form"
render="sub2QuestionGrp"
listener="#{generalQuestionBean2.reset}"/>
</h:selectOneRadio><h:inputText value="#{sub2q.addnInfo}"
rendered="#{sub2q.answer eq '1'}"></h:inputText>
</h:panelGroup></h:column>
</h:dataTable></h:panelGroup>
</h:panelGroup></h:column>
</h:dataTable></h:panelGroup>
</h:panelGroup></h:column>
</h:dataTable>
下面是 backing bean 上的 reset 函数代码:
private void reset(AjaxBehaviorEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
String id = event.getComponent().getClientId(context);
String[] tokens = id.split("[:]+");
int qId = -1;
int subqId = -1;
int sub2qId = -1;
for (int i = 0; i < tokens.length; i++) {
if(tokens[i].equals("questionTable"))
qId = Integer.parseInt(tokens[i+1]);
if(tokens[i].equals("subQuestionTable"))
subqId = Integer.parseInt(tokens[i+1]);
if(tokens[i].equals("sub2QuestionTable"))
sub2qId = Integer.parseInt(tokens[i+1]);
}
Question q = questions.getQuestion(qId);
Question processQ = q;
String defaultSubAnswer = getDefaultSubAnswer(q.getField());
Question subq;
Question subq2;
if(subqId > -1) {
subq = q.getAddnQuestions().get(subqId);
processQ = subq;
if(sub2qId > -1) {
subq2 = subq.getAddnQuestions().get(sub2qId);
processQ = subq2;
}
}
resetValue(processQ, defaultSubAnswer);
}
private void resetValue(Question q, String defaultSubAnswer) {
q.setAddnInfo("");
if(q.getAddnQuestions() != null) {
for (int i = 0; i < q.getAddnQuestions().size(); i++) {
Question subq = q.getAddnQuestions().get(i);
subq.setAnswer(defaultSubAnswer);
resetValue(subq, defaultSubAnswer);
}
}
}
问题来了:
ajax 事件应默认为“valueChange”。如果我单击“是”然后再次单击“是”,则不会发生 ajax 调用,对吗?但它是,因为附加信息框正在清除基于重置功能。
我最初尝试向重置函数添加条件以检查单击按钮的值,并且仅在答案为“0”(否)时重置 addnInfo 值和子问题。但这会导致渲染出现问题,因为 ajax 调用会将输入框和子问题渲染为隐藏,并且该值将保留在前端,即使它们在后备 bean 上被重置。当他们重新渲染到最前面时,显示的是保留的值,而不是支持 bean 中的值。
另一个尝试是使用 ValueChangeListener 来重置值。但这仍然存在与重新渲染时保留的值相同的问题。
我尝试了 3 种不同的方法(如上所列),但都失败了。我愿意听取任何这些或可能的其他解决方案的解决方案。请记住,用户的格式限制使我可以使用的选项更少。
【问题讨论】: