[英]ADF af:showPrintablePageBehavior sends all subsequent navigation commands to a new window
I have a print icon that renders the printable version of the form. 我有一个打印图标,呈现表单的可打印版本。
<af:link id="printButton" icon="/images/printer.png">
<af:showPrintablePageBehavior/>
</af:link>
This part works properly, but after you close the tab created by the <af:showPrintablePageBehavior/>
any attempts to redirect to a new page creates a new browser tab. 这部分工作正常,但在关闭
<af:showPrintablePageBehavior/>
创建的选项卡后,任何重定向到新页面的尝试都会创建一个新的浏览器选项卡。
The button doing the redirect is defined thusly, 这样定义了执行重定向的按钮,
<af:button text="Search" action="#{backing.searchAction}"
partialSubmit="false" immediate="true" id="ab1" />
public String searchAction() {
return "search"
}
"search"
is a navigation-rule, which is defined in the faces-config.xml
and works properly if you do not invoke <af:showPrintablePageBehavior/>
before clicking the button. "search"
是一个导航规则,它在faces-config.xml
定义,如果在单击按钮之前未调用<af:showPrintablePageBehavior/>
,则可以正常工作。
I have tried using ExternalContext.redirect(page)
. 我尝试过使用
ExternalContext.redirect(page)
。 I have also tried defining the targetFrame
attribute to _self
and _parent
for the <af:button>
. 我也尝试将
targetFrame
属性定义为_self
, _parent
为<af:button>
。 The miss-behavior is consistent with each of these approaches. 错失行为与这些方法中的每一种都是一致的。
The root of all evil in your example is the immediate="true"
attribute. 你的例子中所有邪恶的根源是
immediate="true"
属性。 If you just remove it, you'll get your problem solved. 如果您只是删除它,您将解决您的问题。
However, in order to explain why, let's first start with the <af:showPrintablePageBehaviour>
component and the trinidad-config.xml
file (which is nested within the WEB-INF
folder). 但是,为了解释原因,我们首先从
<af:showPrintablePageBehaviour>
组件和trinidad-config.xml
文件(嵌套在WEB-INF
文件夹中)开始。
The trinidad-config.xml
file lists an element, called <output-mode>
. trinidad-config.xml
文件列出了一个名为<output-mode>
的元素。 By default, it's not there, but you can add it manually. 默认情况下,它不存在,但您可以手动添加它。 The element supports three values:
该元素支持三个值:
"default"
(or null
): the default output mode "default"
(或null
):默认输出模式 "printable"
: an output mode suitable for printable pages "printable"
:适用于可打印页面的输出模式 "email"
: an output mode suitable for e-mailing a page's content "email"
:适用于通过电子邮件发送页面内容的输出模式 In order to have a page content displayed as a printable, the output-mode
is changed (usually by the underlying framework) to "printable"
. 为了使页面内容显示为可打印,
output-mode
(通常由底层框架)更改为"printable"
。 So, every time you click on your <af:link>
component, the <output-mode>
value is set to "printable"
. 因此,每次单击
<af:link>
组件时, <output-mode>
值都将设置为"printable"
。
The good thing about trinidad-config.xml
is that we are allowed to use EL expressions within, which means that we can dynamically change the value of the <output-mode>
element. trinidad-config.xml
的好处是我们可以在其中使用EL表达式,这意味着我们可以动态地改变<output-mode>
元素的值。 For example, the value can be read from a @ManagedBean
: 例如,可以从
@ManagedBean
读取值:
<output-mode>#{printableBehaviorBean.outputMode}</output-mode>
The been itself can be a completely simple ( @RequestScoped
) bean. 本身可以是一个完全简单的(
@RequestScoped
)bean。 Note that I'm using annotations instead of XML-based configuration, because you mentioned you're using ADF 12c, which is built on the top of JSF-2. 请注意,我使用的是注释而不是基于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;
}
}
Then, we can inject this bean within another bean, which will help us navigate to the "search"
activity when the Search
button is pressed. 然后,我们可以注入另一个bean,这将有助于我们定位到内这个bean
"search"
的活动时, Search
按钮被按下。 The bean will have a nested @ManagedProperty
member, which will hold an instance of the preceding printableBehaviorBean
bean. 该bean将有一个嵌套的
@ManagedProperty
成员,该成员将保存前面的printableBehaviorBean
bean的实例。 Also, the navigationBean
will introduce a search()
method, which we'll be referred from the Search
button's action
attribute. 此外,
navigationBean
将引入一个search()
方法,我们将从Search
按钮的action
属性中引用它。
The trick here's that before actually returning the navigation outcome, we'll change the value of the outputMode
property in the printableBehaviorBean
. 这里的诀窍是,在实际返回导航结果之前,我们将更改
printableBehaviorBean
outputMode
属性的值。 Remember that this new value will overwrite the existing <output-mode>
value and if the <output-mode>
value was previously set to "printable"
, it will be reverted back to "default"
(and this will happen every time we click the on Search
button). 请记住,这个新值将覆盖现有的
<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";
}
}
And finally, the Search
button definition would be changed slightly to: 最后,
Search
按钮定义将略微更改为:
<af:button text="Search" action="#{navigationBean.search}" immediate="true" id="ab1" />
Now, another question of interest would be "Why removing immediate="true"
solves the problem? . 现在,另一个感兴趣的问题是“为什么删除
immediate="true"
解决问题?
A UICommand
component decorated with immediate="true"
will make the framework skip the "Process validations", "Update model values" and "Invoke application" JSF life-cycle phases (ie the 3rd, 4th and the 5th phase). 用
immediate="true"
装饰的UICommand
组件将使框架跳过“过程验证”,“更新模型值”和“调用应用程序”JSF生命周期阶段(即第3,第4和第5阶段)。 My assumption on your problem would be that before the "Invoke application" phase, the ADF implementation checks if the command components is decorated with a <af:showPrintablePageBehaviour>
component and if it is, then it programmatically changes the value of the <output-mode>
element. 我对你的问题的假设是,在“调用应用程序”阶段之前,ADF实现检查命令组件是否用
<af:showPrintablePageBehaviour>
组件装饰,如果是, <af:showPrintablePageBehaviour>
编程方式更改<output-mode>
的值<output-mode>
元素。 And since you have immediate="true"
on the "Search"
button, this value would be left as "printable"
. 由于您在
"Search"
按钮上有immediate="true"
,因此该值将保留为"printable"
。 That's why when you go back to the form, it triggers a new tab. 这就是为什么当你回到表单时,它会触发一个新选项卡。
So, in conclusion, either remove the immediate="true"
attribute, or follow the workaround with the beans I suggested. 因此,总之, 要么删除
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.