我已经设置了一个简单的演示应用程序(包含用户和消息),可以一起使用jQuery,Ajax和Rails进行测试。我们的想法是,当您将鼠标悬停在用户索引页面上的用户行时,该页面将使用Ajax加载该用户的第一条消息。这在功能上“有效”,但每次鼠标悬停时,获取数据的服务器GET请求数量会翻倍,直到页面慢速爬行为止。任何人都可以帮我弄清楚为什么会这样吗?
显示输出的用户index.html.erb看起来像这样:
...
<% @users.each do |user| %>
<tr class="user_name" id="<%=user.id %>">
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<div id="first_message"></div>
...
我的基于jQuery的Ajax代码(在assets / ajax.js中)如下所示:
$(document).ready(function () {
$('.user_name').mouseover(function() {
var userId = $(this).attr('id');
$('#first_message').load(window.location + userId + "/first_message");
});
});
我添加了以下路由来处理加载消息:
match 'users/:id/first_message' => 'users#first_message'
处理请求的控制器如下所示:
class UsersController < ApplicationController
def first_message
@user = User.find(params[:id])
respond_to do |format|
format.html # first_message.html.erb
end
end
最后,Ajax请求的html响应页面(first_message.html.erb)如下所示:
<h3> <%= @user.name %>'s first message: </h3>
<% if @user.messages.length > 0 %>
<%= @user.messages[0].content %>
<% else %>
...
<% end %>
有什么想法吗?
答案 0 :(得分:1)
我认为下面这一行是在first_message.html.erb
文件中加载的,包括需要ajax.js
文件的布局。因此,您的ajax.js
文件会被反复包含在内。
$('#first_message').load(window.location + userId + "/first_message");
您可以将first_message
视图转换为部分视图,也可以告诉它不要使用所有JS文件渲染布局等:
format.html { render :layout => false } # first_message.html.erb
答案 1 :(得分:0)
除了Dylan Markow提到的关于你的布局的内容之外,你的JS中还有一些性能问题:
当光标进入子元素时,mouseover
事件会触发,因此在这种情况下,每次将鼠标悬停在td
上时。您应该使用mouseenter
来避免这种情况。
http://api.jquery.com/mouseover/
检索完数据后,您应取消绑定事件,以免再次获取相同的信息:
$(function () {
$('.user_name').mouseenter(function() {
var userId = $(this).attr('id');
$('#first_message').load(window.location + userId + "/first_message");
$(this).unbind('mouseenter');
});
});
当然,你丢失了这些数据,因为你没有存储它(选择只使用load
)。您应该使用$.get
并保留数据(您可以通过tr
将其与$(this).data('first-message', httpResponseData);
元素一起存储。)
答案 2 :(得分:0)
不完全确定但看起来在将HTML放在div#first_message
内后,布局也会再次呈现,从而导致再次绑定mouseover
事件。这会导致get请求调用成倍增加。