[英]ADF af:showPrintablePageBehavior sends all subsequent navigation commands to a new window
我有一个打印图标,呈现表单的可打印版本。
<af:link id="printButton" icon="/images/printer.png">
<af:showPrintablePageBehavior/>
</af:link>
这部分工作正常,但在关闭<af:showPrintablePageBehavior/>
创建的选项卡后,任何重定向到新页面的尝试都会创建一个新的浏览器选项卡。
这样定义了执行重定向的按钮,
<af:button text="Search" action="#{backing.searchAction}"
partialSubmit="false" immediate="true" id="ab1" />
public String searchAction() {
return "search"
}
"search"
是一个导航规则,它在faces-config.xml
定义,如果在单击按钮之前未调用<af:showPrintablePageBehavior/>
,则可以正常工作。
我尝试过使用ExternalContext.redirect(page)
。 我也尝试将targetFrame
属性定义为_self
, _parent
为<af:button>
。 错失行为与这些方法中的每一种都是一致的。
你的例子中所有邪恶的根源是immediate="true"
属性。 如果您只是删除它,您将解决您的问题。
但是,为了解释原因,我们首先从<af:showPrintablePageBehaviour>
组件和trinidad-config.xml
文件(嵌套在WEB-INF
文件夹中)开始。
trinidad-config.xml
文件列出了一个名为<output-mode>
的元素。 默认情况下,它不存在,但您可以手动添加它。 该元素支持三个值:
"default"
(或null
):默认输出模式 "printable"
:适用于可打印页面的输出模式 "email"
:适用于通过电子邮件发送页面内容的输出模式 为了使页面内容显示为可打印, output-mode
(通常由底层框架)更改为"printable"
。 因此,每次单击<af:link>
组件时, <output-mode>
值都将设置为"printable"
。
trinidad-config.xml
的好处是我们可以在其中使用EL表达式,这意味着我们可以动态地改变<output-mode>
元素的值。 例如,可以从@ManagedBean
读取值:
<output-mode>#{printableBehaviorBean.outputMode}</output-mode>
本身可以是一个完全简单的( @RequestScoped
)bean。 请注意,我使用的是注释而不是基于XML的配置,因为您提到您使用的是ADF 12c,它建立在JSF-2的顶层。
@RequestScoped
@ManagedBean(name = "printableBehaviorBean")
public class PrintableBehaviorBean {
private String outputMode;
public void setOutputMode(String outputMode) {
this.outputMode = outputMode;
}
public String getOutputMode() {
return outputMode;
}
}
然后,我们可以注入另一个bean,这将有助于我们定位到内这个bean "search"
的活动时, Search
按钮被按下。 该bean将有一个嵌套的@ManagedProperty
成员,该成员将保存前面的printableBehaviorBean
bean的实例。 此外, navigationBean
将引入一个search()
方法,我们将从Search
按钮的action
属性中引用它。
这里的诀窍是,在实际返回导航结果之前,我们将更改printableBehaviorBean
outputMode
属性的值。 请记住,这个新值将覆盖现有的<output-mode>
值,如果<output-mode>
值先前设置为"printable"
,它将恢复为"default"
(每次点击都会发生这种情况) “ Search
按钮)。
@RequestScoped
@ManagedBean(name = "navigationBean")
public class NavigationBean {
@ManagedProperty(name = "printableBehaviorBean", value="#{printableBehaviorBean}")
private PrintableBehaviorBean printableBehaviorBean;
public void setPrintableBehaviorBean(PrintableBehaviorBean printableBehaviorBean) {
this.printableBehaviorBean = printableBehaviorBean;
}
public PrintableBehaviorBean getPrintableBehaviorBean() {
return printableBehaviorBean;
}
public String search() {
printableBehaviorBean.setOutputMode("default");
return "search";
}
}
最后, Search
按钮定义将略微更改为:
<af:button text="Search" action="#{navigationBean.search}" immediate="true" id="ab1" />
现在,另一个感兴趣的问题是“为什么删除immediate="true"
解决问题?
用immediate="true"
装饰的UICommand
组件将使框架跳过“过程验证”,“更新模型值”和“调用应用程序”JSF生命周期阶段(即第3,第4和第5阶段)。 我对你的问题的假设是,在“调用应用程序”阶段之前,ADF实现检查命令组件是否用<af:showPrintablePageBehaviour>
组件装饰,如果是, <af:showPrintablePageBehaviour>
编程方式更改<output-mode>
的值<output-mode>
元素。 由于您在"Search"
按钮上有immediate="true"
,因此该值将保留为"printable"
。 这就是为什么当你回到表单时,它会触发一个新选项卡。
因此,总之, 要么删除immediate="true"
属性, 要么使用我建议的bean遵循变通方法。
由于你使用ADF 12c和Konstantin Yovkov描述了这个问题,也许你可以删除inmediate属性并放入af:button
<af:target events="@all" execute="@this" render="@all"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.