如何在Rails中异步渲染部分/使用AJAX?

时间:2014-03-05 00:57:48

标签: javascript jquery ruby-on-rails ajax asynchronous

当我使用表格滚动到div的底部时,我目前有以下代码加载部分代码:

$(document).ready(function () {
        $("#pastGigs").scroll(function () {
            if (isScrollBottom()) {
                $('#pastGigs tr:last').after('<%= render "layouts/pastGigs" %>');

                $(this).unbind("scroll");
            }
        });

        function isScrollBottom() {

            var elementHeight = $("#pastGigs")[0].scrollHeight;
            var scrollPosition = $("#pastGigs").height() + $("#pastGigs").scrollTop();
            return (elementHeight == scrollPosition);
        };

    });

它工作正常,但我使用partial的原因是因为我不想立即加载所有内容,因为它确实减慢了页面的速度。我应该不使用部分,还是有其他方法来执行脚本并仅在滚动后加载内容?我已经在stackoverflow上看了一下类似的问题,他们都解释了如何渲染部分(我不知道escape_javascript并且手动删除部分中的所有空格...),但似乎没有解决我当前的速度问题。由于部分中的数据量存在大约15秒(!)的差异,这就是我不想同步加载它的原因。

编辑:当前的config / routes.rb:

root "resnate_pages#home"
resources :users, :path => ''

编辑2:终端中的当前错误:

Processing by UsersController#show as */*
Parameters: {"id"=>"pastGigs"}
User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "pastGigs"]]
Completed 404 Not Found in 3ms

ActiveRecord::RecordNotFound (Couldn't find User with id=pastGigs):
app/controllers/users_controller.rb:5:in `show'

2 个答案:

答案 0 :(得分:1)

在查看了所有内容之后,看起来你有正确的想法来渲染部分,除了我们讨论过它实际上并没有异步加载。由于在javascript的主体中有ERB标记,因此ERB实际上在被传递到浏览器之前被呈现为服务器端(正如您所注意到的,具有大量HTML文本)。这似乎起作用的原因(意味着避免你提到的15秒的巨大加载时间)是因为当页面加载时,HTML文本实际上并未被浏览器解释为HTML(此时它只是一个简单的'ol字符串' )。当您使用.after函数将其添加到DOM时,它当然会被解析和评估。

所以基本上我们只需要把这些东西拿出来。很高兴您正在查看jQuery ajax文档;绝对值得花时间和相当丰富的信息。您还可以查看$.get函数。它是发送GET请求的便捷方法;你控制力较弱,但如果这无关紧要,它可以帮助保持清洁。我将使用$.get函数进行演示,如果您需要控件(或者更喜欢另一个),您可以选择使用$.ajax函数。

将其放入scroll功能:

$("#pastGigs").scroll(function () {
    if (isScrollBottom()) {

        $.get("/pastGigs", function(result){
            $('#pastGigs tr:last').after(result);
        });

        $(this).unbind("scroll");
    }
});

您可以根据自己的喜好命名pastGigs路线,仅用于演示目的。确保您在routes.rb

中设置路线
get "/pastGigs" => "users#pastGigs"

OR

get "/pastGigs", to: "users#pastGigs"

同样,我不知道您的控制器被调用了什么,因此请将其替换为系统中正确的操作名称。

最后,控制器动作:

def pastGigs
   render :partial => "layouts/pastGigs"
   # OR
   # render "layouts/pastGigs", :layout => false
end

最终结果是当滚动到达底部时,会向该URL触发ajax调用,并呈现部分并返回到成功函数($.get的第二个参数)。 result变量将包含呈现的HTML部分。

如果有效,请告诉我。

答案 1 :(得分:1)

快速调整Paul的代码,为任何感兴趣的人填充模式:

$('#seeAll').click(function(){
$.get("/pastGigs", function(result){
$('#pastGigsBody').html(result);});
});

当用户点击Past Gigs div中的“See All”时,它会打开包含所有过去演出的模态。感谢Paul教我关于$ .get请求。