1

次のコードを含む 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、次の 2 つのことが起こります。

  1. URL を含む新しいページがitem.urlブラウザーで開かれます。
  2. メソッドlikeditems.itemLinkClicked(item)が呼び出されます (そのメソッドで、特定のリンクがクリックされた回数を更新します)。

最初のものはすでに機能しています(target="_new")。

最初の動作を停止することなく、2 番目のもの (リンクがクリックされた回数を更新するためのメソッド呼び出し) を実装するにはどうすればよいですか?

4

1 に答える 1

2

最初のものはすでに機能しています(target="_new")。

ターゲットは実際には である必要があります_blank


最初の動作を停止することなく、2 番目のもの (リンクがクリックされた回数を更新するためのメソッド呼び出し) を実装するにはどうすればよいですか?

最も単純な (単純な) JSF っぽい方法は<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 コードを生成します。データリストの外に置いて、関数の引数をいじることができます。ただし、エンドユーザーが右クリックしてコンテキスト メニュー項目 (新しいタブで開く、新しいウィンドウ、新しいシークレット ウィンドウで開く、名前を付けて保存、アドレスをコピーするなど) を選択すると、これはまだ機能しません。これは、エンドユーザーがミドルクリックした場合にも機能しません (ミドルクリックのデフォルトのブラウザー動作は「新しいウィンドウで開く」です)。

ZEEFでは、オン クリック、ミドルクリック、または右クリックを URLに変更するスクリプトを使用しています。このスクリプト<a href>は、カウントを更新し、指定された URL に対して実行するサーブレットを呼び出しwindow.open()ます。

与えられた

<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));
    }
}

クリック サーブレットは次のようになります (簡潔にするために、要求パラメーターの検証は省略されています)。

@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 トラッキングを含め、Web サイトの他の多くの機能が機能しなくなります。これも本当にあなたの懸念事項である場合は、そのクリック サーブレットの URL を に直接入れたほうがよいでしょう<h:outputLink value>

于 2015-01-07T20:23:53.953 に答える