Java p:dataTable中的commandButton单击会导致@ViewScoped beanre@Produced应用程序调用后 观点: 制作人
(使用所述的Java p:dataTable中的commandButton单击会导致@ViewScoped beanre@Produced应用程序调用后 观点: 制作人,java,jsf,glassfish,cdi,view-scope,Java,Jsf,Glassfish,Cdi,View Scope,(使用所述的@ViewScopedCDI注释) 表外: <h:inputHidden id="{selectedDataId}"binding="#{selectedDataId}"/> <p:commandButton type="submit" id="callMethod" label="Hidden button" action="#{controller.method
@ViewScoped
CDI注释)
表外:
<h:inputHidden id="{selectedDataId}"binding="#{selectedDataId}"/>
<p:commandButton type="submit"
id="callMethod"
label="Hidden button"
action="#{controller.method(selectedDataId.value)}"/>
最后它工作了,但我无法找出是什么导致first&base方法重新初始化视图范围的bean。查看堆栈跟踪(见下文),它似乎正在重建行
问题:
关于这个问题,有人有什么解释吗?也许有什么需要注意的
堆栈跟踪
其中:getPipelinecheckSearchResults
是用于检索支持表的列表的调用,这会导致调用生产者
我已经看过了:
我阅读了以下文章/问题,但没有更好地理解上述(第一个)解决方案为何如此有效
除非我理解不正确,否则您使用的bean的作用域是视图(Seam 3、CODI或您自己编写的自定义作用域)。只要JSF生命周期在同一个视图上运行(这是一个正确的假设),您就可以了,但是当您更改视图id时,您会惊讶地发现您得到了视图范围bean的一个新实例??视图范围的全部目的是在JSF中保持相同的视图状态,只要您告诉JSF转到不同的视图id,它就会创建一个新的视图状态。在我看来,您实际上在寻找的是对话范围。我找到了一些jsf/primefaces/ee api/glassfish等的源代码来调试该行为,下面是答案: 简言之 如果
组件
:
- 触发导致重定向的操作(
)controller.method
- 并放置在
数据表中
- 而
基于datatable
bean生成其行@ViewScoped
- 调用
后,将重新生成controller.method
所依赖的datatable
bean(当然还有它的所有依赖项)@ViewScoped
2.1.7
中。
查看2.1.19
的源代码,我希望在那里也能看到相同的行为
细节
对于那些在孤独的夏夜大声呼喊的人,他们会问:“为什么?”
导致这种行为的“事件”链(参考来源):
POST
ed发送到服务器应用程序调用
rowEvent&clickEvent
javax.faces.UIData
org.primefaces.component.datatable.datatablebackingp:datatable
的祖父母开始处理事件@
broadcast
方法首先保存最后选定行的索引rowEvent
UIComponent
上调度clickEvent
,在本例中是在按钮上调度
一切都很好,事件开始由
这反过来调用controller.method
,它返回一个重定向String
,事情开始走下坡路
在方法的末尾,重定向字符串
由
这一次看到我们将要重定向时,会快速清除ViewMap
,在179行删除所有@ViewScoped
bean。如果我们考虑一下,这是合乎逻辑的,因为我们正在走出困境
UIData.broadcast
- 广播了内部事件
- 不知道某个内部事件导致重定向,它所做的一切都将被扔到垃圾堆中(因为
)302
- 作为最后一个操作,尝试选择在步骤
4.3.1
@ViewScoped
bean的地方虽然我还没有测试过,但我希望有相同的行为
h:datatable
,p:accordionPanel
,p:carousel
,p:galleria
,p:dataGrid
等等。简而言之,每个组件都是UIData
的子类,并且不提供重定向感知的广播方法。,我想我最近观察到了一个类似的行为。您是否尝试从commandButton action调用myBean的方法而不是控制器?您是否阅读了本文1。尝试将方法调离myBean
。同样的问题。(尽管我不会将逻辑放入模型中,因为它们应该是哑的)。2.是的,请阅读它,但它指的是actionListener
,在我的例子中,re@Produc
是在应用程序调用之后,因此action
找到了正确的方向使用的@ViewScope
是[此处描述的][1][1]另一方面:如果您检查上述场景,问题是在发送到浏览器的实际重定向之前调用了生产者(在步骤2.4和3之间。因此,我们仍然处于POST
请求中,该请求源于单击,并且成功地使用了步骤1.1中生成的@viewscoped
bean。+我知道,一旦离开页面,或者在客户端丢失或未使用正确的ViewState
id,将导致丢失所有@视窗
@ApplicationScoped
public class Controller {
public String method(final Long dataId) {
/* Do business */
return URL_WITH_REDIRECT;
}
}
@ApplicationScoped
public class Producer {
@Named @ViewScoped @Producer
public MyBean getMyBean() {
final MyBean bean = new MyBean();
bean.list = new ArrayList<Data>(); // where Data has a Long id field
/* Do business and populate list */
return bean;
}
}
onclick="$('input[id*=selectedDataId]').val('#{data.id}'); $('button[id*=callMethod]').trigger('click');"
<h:inputHidden id="{selectedDataId}"binding="#{selectedDataId}"/>
<p:commandButton type="submit"
id="callMethod"
label="Hidden button"
action="#{controller.method(selectedDataId.value)}"/>