ADF af:showPrintablePageBehavior 将所有后续导航命令发送到新的 window
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>
been 本身可以是一个完全简单的 (@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"
activity按钮被按下。该 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
组件将使框架跳过 "Process validations"、"Update model values" 和 "Invoke application" JSF 生命周期阶段(即第三、四、五期)。我对你的问题的假设是,在 "Invoke application" 阶段之前,ADF 实现 检查 命令组件是否装饰有 <af:showPrintablePageBehaviour>
组件,如果是,然后它以编程方式更改 <output-mode>
元素的值。由于 "Search"
按钮上有 immediate="true"
,因此该值将保留为 "printable"
。这就是为什么当您返回表单时,它会触发一个新标签。
因此,总而言之,或者 删除 immediate="true"
属性, 或 遵循我建议的 bean 的解决方法。
由于您使用的是 ADF 12c 且 Konstantin Yovkov 描述了该问题,也许您可以删除 inmediate 属性并放入 af:button
<af:target events="@all" execute="@this" render="@all"/>
我有一个打印图标,可以呈现表单的可打印版本。
<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>
been 本身可以是一个完全简单的 (@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"
activity按钮被按下。该 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
组件将使框架跳过 "Process validations"、"Update model values" 和 "Invoke application" JSF 生命周期阶段(即第三、四、五期)。我对你的问题的假设是,在 "Invoke application" 阶段之前,ADF 实现 检查 命令组件是否装饰有 <af:showPrintablePageBehaviour>
组件,如果是,然后它以编程方式更改 <output-mode>
元素的值。由于 "Search"
按钮上有 immediate="true"
,因此该值将保留为 "printable"
。这就是为什么当您返回表单时,它会触发一个新标签。
因此,总而言之,或者 删除 immediate="true"
属性, 或 遵循我建议的 bean 的解决方法。
由于您使用的是 ADF 12c 且 Konstantin Yovkov 描述了该问题,也许您可以删除 inmediate 属性并放入 af:button
<af:target events="@all" execute="@this" render="@all"/>