0

我想要一个链接,当用户点击它时,它应该执行以下操作:

  • 将密钥保存到会话中
  • 使用另一个 JSF 页面打开一个新窗口
  • 它不应该重新加载当前页面

我不知道如何解决这个问题。
当我保存密钥并打开新窗口时,密钥为空。
也许保存密钥的过程太慢了?
以及如何防止页面重新加载?

这是我当前的代码:

JavaScript

function openWin2(url)
{
     var w = 800;
     var h = window.innerHeight - 100;
     var left = ((screen.width-w)/2);
     var top = ((screen.height-h)/2);
     window.open(url, 'Tax', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
}

xhtml

<ui:repeat value="#{main.list}" var="items">
    <h:commandLink action="#{main.setClickedId(items.itemId)}">
        <table onclick="openWin2('immobilie.xhtml')"><tr><td>Hello</td></tr></table>
    </h:commandLink>
</ui:repeat>

ManagedBean
保存

public void setClickedId(String clickedId) {
    this.clickedId = clickedId;

    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, Object> map = context.getExternalContext().getSessionMap();
    if(map.containsKey("id")){map.remove("id");}
    map.put("id", clickedId);
}

加载

FacesContext context = FacesContext.getCurrentInstance();
immoId = context.getExternalContext().getSessionMap().get("id").toString();
4

3 回答 3

0

当我保存密钥并打开新窗口时,密钥为空。也许保存密钥的过程太慢了?

这里的问题是 JavaScript 和服务器端方法在不同的地方运行:

  • JavaScript 代码在客户端浏览器中运行,就像在您的 PC 中本地执行代码一样。

  • 服务器端代码在服务器上运行。浏览器必须向服务器发出请求,服务器将完成其工作并执行action您定义的方法<h:commandLink>,然后向浏览器返回响应。浏览器将处理响应。注意:这是一个非常基本的解释,有关 JSF 请求的更多信息,请阅读JSF 生命周期和自定义组件

知道这一点,并不是方法执行太慢,而是在不同的时间执行。

以及如何防止页面重新加载?

简而言之,您必须向服务器发出 ajax 请求,而不是完整的请求。为了实现这一点,JSF 2 为您提供<f:ajax>了将简单请求转换为 ajax 请求的功能,并且浏览器不会刷新页面。

解决方案应该是一个两步过程:

  1. 执行服务器操作以将会话中的数据保存为 ajax 请求。

  2. 处理完 ajax 请求后,您应该使用 JavaScript 打开窗口。

<f:ajax>组件本质上不提供oncompletejavascript 方法,但您可以在完成 ajax 请求后利用该onevent方法的强大功能执行 javascript 代码。该示例基于JSF 2.0 javascript onload/oncomplete

<h:commandLink action="#{main.setClickedId(items.itemId)}" value="Hello">
    <f:ajax onevent="handleOnComplete" />
</h:commandLink>

<h:outputScript>
    function handleOnComplete(e) {
        if (e.status == 'success') {
            openWin2();
        }
    }
</h:outputScript>

另一种方法是使用第三方库<a4j:commandLink>,如 RichFaces 或<p:commandLink>PrimeFaces。我将使用 PrimeFaces 代码发布示例:

<p:commandLink action="#{main.setClickedId(items.itemId)}" value="Hello"
    oncomplete="openWin2()" />
于 2013-02-02T19:16:17.720 回答
0

我自己发现了失败。
问题是,JSF 页面没有解析 JSF 标签。
从:

<h:outputText value="#{items.itemId" />

我没有任何输出。
这就是为什么我认为 JSF 页面调用方法失败的原因。
但这不是问题所在。问题是我的网址。这是我打开第二页的代码:

openWin2('immobilie.xhtml')

但那是错误的。它一定要是

openWin2('faces/immobilie.xhtml')

我从这里得到了解决方案。


Luiggi Mendoza 非常感谢您对我的帮助!你对我帮助很大!


于 2013-02-05T21:14:50.220 回答
0

我建议使用a4j:ajax标签(在 RichFaces 中可用,此处的文档)。那么 xhtml 中的标记应该如下所示:

<h:commandLink action="#{main.setClickedId(items.itemId)}">
    <table><tr><td>Hello</td></tr></table>
    <a4j:ajax oncomplete="openWin2('immobilie.xhtml')" />
</h:commandLink>

这段代码会向服务器发送一个 AJAX 请求,服务器会执行 method setClickedId,当响应返回给浏览器时,openWin2会调用该函数。

于 2013-02-02T11:53:36.250 回答