Ruby on Rails Ajax 调用运行控制器代码,返回成功,但不呈现视图 [英] Ruby on Rails Ajax call runs controller code, returns success, but not rendering view

查看:44
本文介绍了Ruby on Rails Ajax 调用运行控制器代码,返回成功,但不呈现视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的页面上有一个有效的搜索机制;带有文本字段和带有搜索"标签的提交按钮的表单.

I have a working search mechanism on my page; a form with a text field and 'search'-labelled submit button.

我的页面上还有一个基于 raphael.js 的动画项目,上面有我想要执行搜索的可点击项目.

I’ve also got an animated raphael.js-based item on my page, with clickable items on it that I want to result in an executed search.

点击时,我将数据发送到我的控制器参数,这些数据旨在作为从 raphael 对象中提取的搜索词.

On click, I send to my controller params data intended to be search terms taken from the raphael objects.

正在传递数据,并且控制器代码运行,但相应的视图无法呈现,因此单击对用户来说似乎什么都不做.

The data is being passed, and the controller code runs, but the corresponding view fails to render so the click appears to the user to do nothing.

所以点击后,我会像这样进行 Ajax 调用:

So on click, I make an Ajax call like this:

            // Add a search function
            circle.click(function (e) {
                var csrch = this.data('label');
                // alert('clicked ' + csrch);
                e.preventDefault();
                $.ajax({
                    type: "GET",
                    url: "/bubbleBar",
                    data: $.param({ srchterm: csrch} ),
                    success: function(){
                        // window.location.replace("/pictures");
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown) {
                        alert("--- error: " + errorThrown);
                    }
                });
            });

我的控制器中的‘bubbleBar’动作成功触发,传输搜索词,并重定向到我处理搜索的工作索引动作:

The ‘bubbleBar’ action in my controller fires successfully, transfers the search terms, and redirects to my working index action, which handles searches:

def bubbleBarSearch
    redirect_to pictures_path(:srchterm => params[:srchterm])
end

def index
    # Initialize the pictures array
    #
    @pictures = Picture.first
    if params[:srchterm].present?

        # If the search button was hit, search pictures for the terms
        @pictures = []
        results = Picture.search(params[:srchterm], page: params[:page])
        results.each do |x|
            @pictures << x
        end

        # Also search keywords for the search terms
        #
        keywords = Keyword.search(params[:srchterm], page: params[:page])

        # Retrieve images based on keywords
        #
        keywords.each do |kw|
            pics = Picture.where(:id => kw.picture_id)
            pics.each do |pic|
                # Only add to results if unique
                #
                if !@pictures.include? pic
                    @pictures << pic
                end
            end
        end
        respond_to do |format|
            format.html {
                puts '---------------- ding -----------------'
                # Redirect_to pictures_path
            }
            format.js {alert('dong');}
        end
    else
        @pictures = Picture.all.order("RANDOM()")
    end
end

我遇到的问题是 Ajax 返回成功,但索引"操作的相应视图没有呈现.

The problem I’m having is that Ajax returns success, but the corresponding view for the ‘index’ action does not render.

如果我取消注释 'window.location.replace("/pictures");'在我的 JavaScript 代码行中,我可以强制渲染成功,但我丢失了控制器代码为我获得的搜索结果.如果我取消注释控制器中的redirect_to Pictures_path"行,我当然会得到一个错误的无限循环.

If I uncomment the 'window.location.replace("/pictures");' line in my JavaScript code, I can force the render on success, but I lose the search results that the controller code got for me. If I uncomment the 'redirect_to pictures_path' line in my controller, I of course get an infinite loop that errors out.

到目前为止我所做的研究表明我应该在控制器中捕获响应.

Research I’ve do done so far tells me I should be catching the response in the controller.

我之前没有使用过 respond_to,看起来 format.html 会被 Ajax 调用命中,但是当我使用页面上已经设置的搜索字段/按钮机制手动进行搜索时也会触发.我不清楚为什么我的 Ajax 调用是以 HTML 而非 JavaScript 形式出现的.

I’ve not worked with respond_to before, and it appears that format.html gets hit with the Ajax call, but ALSO fires when I manually do the search using the search field/button mechanism already set up on the page. I'm unclear as to why my Ajax call comes in as HTML rather than JavaScript.

所以这意味着如果我在控制器中手动处理视图的渲染,当搜索没有通过已经工作的机制并且冒着渲染页面两次或以其他方式引入的风险时,我不会捕捉到这种情况我的网站出现故障.

So that means if I handle the rendering of the view manually in the controller, I’m not catching the case when the search hasn’t come through the already working mechanism and running the risk of rendering a page twice or otherwise introducing malfunction into my site.

我不知道如何在控制器操作发生后使我的点击/Ajax 调用成功地从点击功能呈现所需的视图.我在这里缺少什么?实现这一目标的理想方法是什么,并且不会丢失我成功渲染所需的控制器数据?

I’m lost on how to make my click/Ajax call successfully render the desired view from the click function after the controller action happens. What am I missing here? What is the ideal methodology to achieve this, and not lose the controller data I need to successfully render?

Ruby on Rails 的输出表明服务器认为它正在呈现正确的 Haml 视图文件,但是我在文件底部放置了一个 JavaScript 标记以将输出记录到控制台,单击后控制台为空.如果我通过站点导航到同一视图,则语句将输出到控制台.

Outputs from Ruby on Rails indicate that the server believes it is rendering the proper Haml view file, however I placed a JavaScript tag at the bottom of the file to log output to console and the console is empty after a click. If I navigate to the same view through the site, the statement is output to the console.

我修改了我的 Ajax 成功回调以包含一个参数,并且经过检查,该变量包含视图的 HTML 代码.那么 Ruby on Rails 是将输出定向到 Ajax 而不是浏览器吗?然后如何从 Ajax 成功回调中呈现该输出?

I've modified my Ajax success callback to have a parameter, and upon examination the variable contains the HTML code for the view. So is Ruby on Rails directing the output to Ajax instead of the browser? How can I then render that output from the Ajax success callback?

对控制器的成功调用包含一个 utf8 参数,该参数不在我的 Ajax 调用中.这是一个因素吗?

Successful calls to the controller contain a utf8 parameter that is not in my Ajax call. Is this a factor?

推荐答案

重定向的工作方式是返回一个重定向状态码给浏览器,这会导致浏览器对响应头中返回的 url 进行后续请求.因此,问题是您的 bubbleBarSearch 操作返回状态为重定向到您的 ajax 调用.它实际上并没有在您的索引操作中运行代码.为什么不为您的索引操作创建一个路由并直接调用它?

Redirects work by returning a status code of redirected to the browser, which causes the browser to make a subsequent request to the url returned by in the response header. So, the problem is that your bubbleBarSearch action is returning with a status of redirected to your ajax call. It is not actually running the code in your index action. Why not just make a route for your index action and call it directly?

编辑 - 所以这是错误的,我明白你现在在问什么.要在回复中回答您的问题:

Edit - So that was wrong, I see what you are asking now. To answer your question in your reply:

啊,我明白了,您似乎想要按照 AlexeyKuznetsov 的建议去做.

Ah, I see, it looks like you want to do what AlexeyKuznetsov suggested.

你需要 if request.xhr 而不是 respond_to do |format|.当您发出 ajax (xhr) 请求时, request.xhr 条件将为真,否则 rails 知道它是标准请求.我认为您的问题是您没有正确响应,这将呈现并返回它的视图呈现的任何 html,并将其返回到您的 ajax 请求.您可以告诉 rails 为不同类型的请求进行不同的呈现.要使用 javascript 片段进行响应,您可以使用 render js: (http:///guides.rubyonrails.org/layouts_and_rendering.html 搜索 Rendering Vanilla JavaScript) like

Instead of respond_to do |format| you'll want if request.xhr. When you make an ajax (xhr) request, the request.xhr condition will be true, otherwise rails knows its a standard request. I think your issue is that you are not responding correctly, this will render and return whatever html it's view renders, and return it to your ajax request. You can tell rails to render differently for different types of requests. To respond with a javascript snippet, you can use render js: (http://guides.rubyonrails.org/layouts_and_rendering.html search for Rendering Vanilla JavaScript) like

if request.xhr
  render js: "alert('dong')"  # this is an ajax request
else
  puts '-------- ding ---------` # this is not

或者你可以渲染 json render json:,它会传回一个 json 响应.

or you can render json render json:, which will pass back a json response.

if request.xhr
  render json: {message: "ding"}
else
  puts '-------- ding ---------` # this is not

然后在您的 axax 成功函数中:

then in your axax success function:

success: function(data){
  console.log(data) // will have message: ding
  // window.location.replace("/pictures");
},

这篇关于Ruby on Rails Ajax 调用运行控制器代码,返回成功,但不呈现视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆