【问题标题】:Will PrimeFaces Dialog Framework break view scope as compared to p:dialog?与 p:dialog 相比,PrimeFaces Dialog Framework 会破坏视图范围吗?
【发布时间】:2014-12-17 00:07:48
【问题描述】:

我正在使用 PrimeFaces 5。

我想在按下按钮时打开一个对话框。

<p:commandButton value="add upload" actionListener="#{theForm.openUpload}" >

public void openUpload() {
    this.item = new Item();
    RequestContext.getCurrentInstance().openDialog("uploadForm");
}

对话框中会有一个保存按钮来保存输入。

<h:commandButton value="#{text['button.add']}" id="add" styleClass="btn btn-default" actionListener="#{theForm.confirmAdd}"/>

public void confirmAdd() {
    RequestContext.getCurrentInstance().closeDialog("uploadForm");
}

我的托管 bean 是 @ViewScoped。如果对话框像 PrimeFaces 对话框框架那样位于外部文件中,命令按钮会破坏视图范围吗?每当我单击“添加上传”按钮时,就会再次调用@PostConstruct 方法,就像丢失了范围一样。

official blog 的评论部分说它不会破坏视图范围,但 here the forum a core developer 说 openDialog() 创建一个新视图,因此它会破坏视图范围。

有人可以确认吗?

【问题讨论】:

  • 您使用哪个版本的 JSF?众所周知,javax.faces.bean.ViewScoped 在某些情况下会中断。 (另请参阅 balusc.blogspot.de/2010/06/…)如果您使用 CDI,则应切换到 javax.faces.view.ViewScoped - 这按预期工作。

标签: jsf primefaces dialog view-scope


【解决方案1】:

PrimeFaces 的对话框框架基本上在&lt;iframe&gt; 标记中显示另一个视图。我不会称之为打破视图范围,但对话框视图将有它自己的范围,因为它实际上是一个不同的页面。在不同的情况下,这可能是可取的,也可能是不可取的。正如 PrimeFaces 的用户指南所说:

Dialog Framework (DF) 用于打开外部 xhtml 页面 在运行时动态生成的对话框。

  • p:对话框
    • 存在于同一视图范围内。
    • 可以轻松拥有相同的对话上下文。
    • 静态定义,对话框及其组件立即在构建视图上创建。您只能延迟渲染,例如dynamic=true。
    • 声明式定义意味着它更具可读性和可维护性,因为对话框的存在并没有隐藏在 java 代码中的某个地方。
  • 对话框架。
    • 有自己的视图范围。
    • 开发人员必须担心传递参数、传播对话上下文。 (而且 PF 直到 5.1 才支持includeViewParams。)
    • 动态创建意味着对话框及其组件在对话框实际打开之前不会创建,但每次打开时都会创建一个新对话框。如果对话框多次打开,总的性能损失会更大,而且许多对话框视图会耗尽 JSF 视图限制并使其他视图失效。
    • 命令式动态创建在某些情况下可以提高资源效率。例如。根据用户输入显示数十个特定对话框中的一个。或者很少使用的对话框,可以从应用程序的任何页面打开。

我的建议是默认使用 p:dialog。仅在我在上一个要点中提到的情况下使用对话框框架。

【讨论】:

  • 非常有用的信息!我最终使用 p:dialog 因为符合我的要求:)
【解决方案2】:

这很正常,因为您已经在 main.xhtml 中实例化了 theForm(ManagedBean)。所以范围已经在 main.xhtml 中使用。 当您点击打开对话框时:对话框是一个新视图,然后创建一个新的 theForm 实例(ManagedBean)。

【讨论】:

    【解决方案3】:

    我们在JBoss 7.1/Mojarra 2.1.7 中的@ViewScoped 有一些问题,我们改为Omnifaces

    我建议你使用@org.omnifaces.cdi.ViewScoped 而不是@javax.faces.bean.ViewScoped

    我用你的例子和这里的日志进行了测试,你可以看到不同之处:

    使用@org.omnifaces.cdi.ViewScoped登录

    18:58:40,887 INFO  [xxx.TheForm] (http-localhost-127.0.0.1-8080-2) @postconstruct
    18:58:40,890 INFO  [xxx.TheForm] (http-localhost-127.0.0.1-8080-2) openUpload()
    

    使用@javax.faces.bean.ViewScoped登录

    19:01:19,753 INFO  [xxx.TheForm] (http-localhost-127.0.0.1-8080-5) @postconstruct
    19:01:19,753 INFO  [xxx.TheForm] (http-localhost-127.0.0.1-8080-5) @postconstruct
    19:01:19,754 INFO  [xxx.TheForm] (http-localhost-127.0.0.1-8080-5) openUpload()
    

    【讨论】:

    • Stackoverflow 不是一个可以劫持一些线程的 论坛。 Stack Overflow 是一个 Q&A 网站,每个 page 有 一个 问题和许多答案 - 请提出您自己的问题,即使它与这篇文章的内容非常相似!
    • 我认为他没有劫持线程,他建议我使用另一个包,因为他遇到了同样的问题
    • @Kossel 看起来像一个问题(我们有同样的问题),但你可能是对的。
    • @dognose 我试图帮助说我们遇到了同样的问题,我们使用了omnifaces来解决我们的问题。抱歉,问题是我的英语很差 -_- 现在说话,而我想过去说话。
    • @henriquedsg89 没问题。只是一个小小的误会:)
    猜你喜欢
    • 2020-04-30
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 2014-01-23
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多