2011-11-04 24 views
1

我已經設置了一個簡單的演示應用程序(用戶和消息)來測試使用jQuery,Ajax和Rails在一起。這個想法是,當您在用戶索引頁面上將用戶行鼠標懸停時,該頁面將使用Ajax來加載該用戶的第一條消息。這在功能上「有效」,但每次鼠標懸停時,獲取數據的服務器GET請求的數量加倍,直到頁面變慢。任何人都可以幫我弄清楚爲什麼會發生這種情況?jQuery ajax請求Rails服務器每次翻倍

,顯示輸出的用戶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代碼(在資產/ 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 

最後的HTML響應頁面(first_message.html.erb)爲Ajax請求如下:

<h3> <%= @user.name %>'s first message: </h3> 
<% if @user.messages.length > 0 %> 
    <%= @user.messages[0].content %> 
<% else %> 
     ... 
<% end %> 

有什麼想法?

回答

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 
+0

是的,就是這樣,謝謝! – Perikles

0

除了什麼迪倫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並保留數據(可以通過$(this).data('first-message', httpResponseData);將其與tr元素一起存儲)。

+0

太棒了,感謝所有提高我的代碼的提示。 – Perikles

0

不完全確定,但看起來好像將HTML放入div#first_message之後,佈局也會再次呈現,導致再次綁定mouseover事件。這將導致get請求調用得到倍增。