异步调用控制器操作以返回与image_tag一起使用的URL

时间:2016-09-04 17:49:36

标签: ruby-on-rails ruby ajax

我目前有以下视图,即正在加载一堆图像,一个用于数组中的每个字符。问题是get_character_thumbnail调用api来获取图像url,并且当用户请求页面数据时,它会同步完成。

    <% @comic.characters.each do |character| %>
        <div class = "col-sm-6 col-md-3">
            <div class = "thumbnail">
                <%= image_tag(get_character_thumbnail(character)) %>
            </div>
            <div class = "caption">
                <p><%= character['name'] %></p>
            </div>
        </div>
    <% end %>

我想强制每次对get_character_thumbnail(character)的调用都是异步完成的,页面不会卡住。

def get_character_thumbnail(character)
    response = HTTParty.get(character['resourceURI'], get_basic_api_options)
    response['data']['results'][0]['thumbnail']['path'] + '/portrait_large.jpg'
end

因为我对rails上的ruby很新,所以我正在努力设置一个ajax调用来完成这个技巧。有没有人有建议或链接可以帮助我?

2 个答案:

答案 0 :(得分:1)

您的路线应始终立即返回响应。这是您编写自定义端点以提供单个角色图像的一种方法。您的html页面会快速加载,然后您可以将img src属性设置为指向图像路径。

以下是一些示例代码:

一些html.erb模板

<% @comic.characters.each do |character| %>
  <img src='/character_image/<%= character.id %>'>
<% end %>

新路线get '/character_image/:id'

def character_image
  @char = Character.find(id: params[:id])
  img_path = "tmp/char_img_#{@char.id}.jpg"
  unless File.exists?(img_path)
    img_url = get_char_img(@char) # hit your API to get the url
    `wget #{img_url} -O #{img_path}`
  end
  send_file img_path, type: 'image/jpg', disposition: 'inline'
end

如果您的html页面已刷新,此代码将缓存图像以避免重复的API请求。

我在这里使用tmp/,因为它是Heroku上的一个启用写入的位置(阻止文件系统写入其他位置)。在其他环境(例如本地)上,您可以选择将图像保存到public/,默认情况下Rails会静态提供。

答案 1 :(得分:1)

您应该进行AJAX调用并获取所有图像作为响应。 然后存储在Javascript对象中。

页面冻结的原因 -

  1. 因为您可能没有使用JavaScript的闭包概念。当我们在浏览器上加载/读取多个图像文件时,会发生这种情况,因为在第一次迭代中,File-1没有加载并且它跳转到下一次迭代,这有时会导致不加载少量随机图像文件并冻结浏览器。
  2. 您可以查看我的图片预览库(https://github.com/palash-kulkarni/image_uploader/blob/master/image-uploader-1.0.0.js)。它正在进行中,但我知道它肯定会对你有所帮助。

    演示链接(https://github.com/palash-kulkarni/image_uploader/tree/master/Demo

    $.each(files, function (_, file) {
        if (image.types.test(file.type)) {
            that.displayPreview(file, categoryName, image);
            that.bindSingleDeleteEvent(categoryName, image);
        } else {
            that.clientMessage.display('#flash', image.failureMessage.invalidFileType);
        }
    });
    // Iterate object of images 
        reader = new FileReader();
        reader.onload = (function (img) {
            return function (event) {
                img.attr('src', event.target.result);
            };
        })(img);
        reader.readAsDataURL(imageFile);
    // End Iterator