【问题标题】:JSF commandButton 'strange' behaviourJSF commandButton“奇怪”行为
【发布时间】:2011-12-21 15:06:23
【问题描述】:

我会很高兴为以下案例得到一个体面的解释。

这是一个简单的 JSF,有两种形式和文本输出:

<h:body>
<h:form>
<h:commandButton value="Go" action="#{wierdBean.doWierdStuff}"/>
</h:form>

<h:form>
<h:dataTable value="#{wierdBean.pages}" var="page">
<h:column>
<h:commandButton value="the same go action?" action="#{wierdBean.doWierdStuff}"/>
</h:column>
</h:dataTable>
</h:form>
</h:body>

<h:dataTable value="#{wierdBean.pages}" var="page">
<h:column>
<h:outputText value="#{page}"/>
</h:column>
</h:dataTable>

顶部的“Go”按钮应该做同样的事情 作为“相同的行动?”按钮。

支持 WierdBean 是:

public class WierdBean implements Serializable {

private int buttonsCount;

public WierdBean() {
System.out.println("WierdBean()");
}

@PostConstruct
public void postConstruct() {
System.out.println("postConstruct()");
}

public Integer[] getPages() {
System.out.print("getPages() buttonsCount(): " + buttonsCount);
Integer[] pages = new Integer[buttonsCount];
for (int i = 0; i < pages.length; i++) {
pages[i] = new Integer(i);
}
return pages;
}

public String doWierdStuff() {
System.out.println("doWierdStuff()");
buttonsCount = 2;
return "wierd";
}
}

当我进入页面时,我得到:

INFO: WierdBean()
INFO: postConstruct()
INFO: getPages() buttonsCount(): 0 (16 times)

我只看到了“开始”按钮。这是可以理解的。

按下“开始”按钮后,我得到:

INFO: WierdBean() 
INFO: postConstruct() 
INFO: getPages() buttonsCount(): 0 (19 times) 
INFO: doWierdStuff() 
INFO: getPages() buttonsCount(): 2 (16 times)

很好,调用了 doWierdStuff,然后我得到 2 个“相同的执行操作”按钮和 2 个文本输出。 没关系。

但是,当我按下任何“相同操作”按钮时,它们应该执行 与“开始”按钮相同 - 调用 doWierdStuff 方法 - 我得到:

INFO: WierdBean() 
INFO: postConstruct() 
INFO: getPages() buttonsCount(): 0 (44 times)

只有“开始”按钮可见。

这是为什么呢?

【问题讨论】:

  • 我想我自己找到了答案。我将 getPages 方法中的代码放在 doWierdStuff 中,使 getPages 成为合法的 getter。在这种情况下,无论我做什么,我都只会得到“GO”按钮。让你的 getter 成为 GETTERS ONLY 的另一个原因!

标签: jsf datatable action


【解决方案1】:

您的具体问题有两个方面:bean 显然是请求范围而不是视图范围,并且您在 getter 方法而不是 (post) 构造函数或 (action)listener 方法中进行业务工作。

在每个单独的请求上都会重新创建请求范围的 bean,并且不会在同一视图上的后续请求中重用。所有像buttonsCount 这样的属性都被重新初始化为它们的默认值。单击数据表中的命令链接/按钮时,您需要确保保留与初始请求中完全相同的数据模型。如果您不这样做,JSF 将无法找到要调用的操作。只要您通过返回null 或void 与同一个视图交互,bean 就需要存在。这可以通过将 bean 放入 @ViewScoped 的视图范围中来实现(或者当您仍在使用过时的 JSF 1.x 时,通过 Tomahawk 的 &lt;t:saveState&gt; 组件)。

支持 bean getter 方法应该只返回已经预先准备好的数据,而不是准备数据本身。 getter 方法应该只是数据的访问点。这是因为 getter 方法可以在请求-响应周期内多次调用,尤其是在 UIData 组件和/或 rendered 属性中引用时。

另见:

【讨论】:

  • 谢谢。那是一个很好的答案! :) 特别是关于数据模型的部分。这就解释了为什么这些按钮有点“迟钝”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2013-09-05
  • 1970-01-01
  • 2011-08-13
  • 2012-12-22
  • 1970-01-01
相关资源
最近更新 更多