如何计算单击h:outputLink的次数?

时间:2015-01-07 19:16:13

标签: jsf primefaces primefaces-mobile

我有一个PrimeFaces页面,其中包含以下代码:

<pm:content id="content">
    <p:dataList value="#{likeditems.likedItems}" var="item" pt:data-inset="true" paginator="true" rows="5">
        <f:facet name="header">
            Products you liked in the past
        </f:facet>
        <h:outputLink value="#{item.url}" target="_new">
            <p:graphicImage name="http://example.com/my-product-mobile/f/op/img/underConstructionImage.jpg" />
            <h2>#{item.title}</h2>
            <p>Approx. #{item.price} (for most up-to-date price, click on this row and view the vendor's page)</p>
        </h:outputLink>
        <f:facet name="footer">
            Products you liked in the past
        </f:facet>
    </p:dataList>
</pm:content>

当用户点击h:outputLink时,我想要做两件事:

  1. 在浏览器中打开一个包含网址item.url的新网页。
  2. 调用方法likeditems.itemLinkClicked(item)(在该方法中,我更新了单击特定链接的次数)。
  3. 第一件事已经有效(target="_new")。

    如何在不首先停止工作的情况下实现第二个(更新链接被点击次数的方法调用)?

1 个答案:

答案 0 :(得分:2)

  

第一件事已经有效(target="_new")。

The target should actually be _blank


  

如何在不首先停止工作的情况下实现第二个(更新链接点击次数的方法调用)?

最简单(天真)的JSF-ish方式会在点击时触发<p:remoteCommand>

<h:outputLink value="#{item.url}" target="_blank" onclick="count_#{item.id}()">
    ...
</h:outputLink>
<p:remoteCommand name="count_#{item.id}" action="#{likeditems.itemLinkClicked(item)}" />

但这会产生大量重复的JS代码,这些代码不是很有效。您可以将它放在数据列表之外,并使用函数参数。但是当最终用户右键单击并选择上下文菜单项(在新选项卡中打开,新窗口,新的隐身窗口,另存为,复制地址等)时,这仍然不起作用。当最终用户middleclicks(middleclick的默认浏览器行为是“在新窗口中打开”)时,这也不起作用。

ZEEF,我们使用的脚本会在点击,middleclick或右键单击时更改<a href>到URL,该URL会调用更新计数的servlet,然后执行window.open()给定的URL。

给出

<h:outputLink value="#{item.url}" styleClass="tracked" target="_blank">

相关脚本基本上应该是这样的:

// Normal click.
$(document).on("click", "a.tracked", function(event) {
    var $link = $(this);
    updateTrackedLink($link);
    var trackingURL = $link.attr("href");
    $link.attr("href", $link.data("href"));
    $link.removeData("href");
    window.open(trackingURL);
    event.preventDefault();
});

// Middle click.
$(document).on("mouseup", "a.tracked", function(event) {
    if (event.which == 2) {
        updateTrackedLink($(this));
    }
});

// Right click.
$(document).on("contextmenu", "a.tracked", function(event) {
    updateTrackedLink($(this));
});

// Update link href to one of click count servlet, if necessary.
function updateTrackedLink($link) {
    if ($link.data("href") == null) {
        var url = $link.attr("href");
        $link.data("href", url);
        $link.attr("href", "/click?url=" + encodeURIComponent(url));
    }
}

并且click servlet应如下所示(为简洁起见省略了请求参数验证):

@WebServlet("/click")
public class ClickServlet extends HttpServlet {

    @EJB
    private ClickService clickService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String url = request.getParameter("url");
        clickService.incrementClickCount(url);
        response.sendRedirect(url);
    }

}

请注意,这样target="_blank"不是必需的。它仅供禁用JavaScript的用户使用。但是,网站上的其他许多东西无论如何都不会起作用,包括上面的JS跟踪。这也是你真正关心的问题,那么你最好直接将点击servlet URL放在<h:outputLink value>中。