这不起作用
<h:form style="display: inline;">
<h:outputLink value="#{title.link}" >
#{msg['g.readMore']}
<f:ajax event="click" immediate="true" listener="#{titlesBean.titleClicked(title.id)}" />
</h:outputLink>
</h:form>
我想要它做的是点击呼叫#{titlesBean.titleClicked(title.id)}
然后转到链接。调用该方法但不会转到链接。还有其他几种方法(使用commandLink然后重定向,但我想知道为什么这不起作用)。
这是方法本身:
public String titleClicked(long titleId) {
this.titlesManager.addXtoRating(titleId, 1);
return null;
}
注意:这只是一个旁注,但我不小心发现这有效:
<script type="text/javascript">
$('.share').popupWindow({centerBrowser:1,height:380,width:550});
</script>
<h:form style="display: inline;">
<h:outputLink styleClass="share" value="http://www.facebook.com/sharer.php...">
<img src="images/facebook-icon.jpg" />
<f:ajax event="click" immediate="true" listener="#{titlesBean.titleLiked(title.id)}" />
</h:outputLink>
</h:form>
查看styleClass="share"
更新 :(我的代表不到100,所以我无法回答我自己的问题8小时,这就是如何巧妙地说 - 愚蠢)。 我等了一会儿,但没有人回答。
所以这是我的黑客攻击解决方案(我根本不喜欢它,但它有效):
<h:form style="display: inline;">
<h:outputLink target="_blank" styleClass="click8" value="#{title.link}" >
#{title.heading}
<f:ajax event="click" immediate="true" listener="#{titlesBean.titleLiked(title.id)}" />
</h:outputLink>
</h:form>
这是重要的部分:
<h:head>
<script type="text/javascript">
$(document).ready(function(){
$('.click8').click(function (event){
var url = $(this).attr("href");
window.open(url, "_blank");
event.preventDefault();
});
});
</script>
</h:head>
注意:这必须在标题中,否则我有一个主要的错误,链接打开一千个窗口。
答案 0 :(得分:4)
它不起作用,因为这里存在竞争条件。在同一窗口中同时发送了两个HTTP请求。一个到服务器的ajax和一个与给定链接正常的ajax。越快完成的那个胜利。您想要同步发送HTTP请求。首先是ajax到服务器,当它返回时,然后正常的到给定链接。
至于你的hacky解决方案,它的工作原理是因为它使用JavaScript在新窗口中打开URL而不是当前的URL然后阻止链接的默认操作,因此正常响应只是到达一个完全独立的窗口而ajax响应仍然在初始窗口中到达。因此,在初始窗口中不再存在两个HTTP请求的竞争条件。
对于最终解决方案,使用标准的JSF 2.0组件集是不可能的。使用<h:commandLink>
然后进行重定向确实可行,但链接这种方式不能被搜索机器人抓取,它会有效地触发POST请求,这比IMO更糟糕的是你的新窗口解决方案。
如果您真的想在当前窗口中打开链接,请将目标网址保留在链接的href中,然后我建议您创建一个简单的servlet来执行链接跟踪和重定向作业让jQuery在onclick
期间操纵链接目标。
像这样的东西
<a rel="ext" id="ext_#{title.id}" href="#{title.link}">read more</a>
(HTML元素ID可能不以数字开头!因此ext_
前缀,您当然可以根据需要改变它。)
与
$(function() {
jQuery('a[rel=ext]').click(function(e) {
var link = jQuery(this);
var url = 'track'
+ '?id=' + encodeURIComponent(link.attr('id'))
+ '&url=' + encodeURIComponent(link.attr('href'));
if (link.attr('target') == '_blank') {
window.open(url);
} else {
window.location = url;
}
e.preventDefault();
});
});
和
@WebServlet(urlPatterns={"/track"})
public class TrackServlet extends HttpServlet {
@EJB
private TrackService trackService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
String url = request.getParameter("url");
if (id == null || url == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
trackService.track(id.replaceAll("\\D+", "")); // Strips non-digits.
response.sendRedirect(url);
}
}