我可以用json渲染图像吗?

时间:2015-01-30 16:16:05

标签: javascript jquery ruby-on-rails json render

我使用Typeahead来渲染我的用户"用户"下拉列表中的模型:

控制器:

def typeahead
  render json: User.where(name: params[:query])
end

查看:

<input type="text" id="typeahead">
<script type="text/javascript">
  var bloodhound = new Bloodhound({
    datumTokenizer: function (d) {
      return Bloodhound.tokenizers.whitespace(d.value);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,

    remote: '/typeahead/%QUERY', 
    limit: 50
  });
  bloodhound.initialize();

  $('#typeahead').typeahead(null, {
    displayKey: 'name',
    source: bloodhound.ttAdapter()
  });

  $('#typeahead').bind('typeahead:selected', function(event, datum, name) {
    doSomething(datum.id);
  });
</script>

此代码会导致User.name列表在我输入时下拉。

我可以渲染图片,在这种情况下是User.avatar.url(:thumb)吗?当我将displayKey: 'name',更改为displayKey: 'avatar.url(:thumb)',时,下拉列表只会显示&#34; undefined&#34;为每个用户。

[我确保User.avatar.url(:thumb)在其他地方成功显示]

2 个答案:

答案 0 :(得分:2)

您需要在服务器上将图像编码为base64,然后在json响应中返回结果字符串,最后在客户端使用此base64字符串填充图像

1 - 服务器端:将图像编码为base64

def typeahead
  users = User.where(name: params[:query])

  json = users.collect do |user|
    path = user.avatar.url(:thumb)
    image = open(path) { |io| io.read }
    base64 = ActiveSupport::Base64.encode64(image)

    {id: user.id, name: user.name, base64: base64}
  end

  render json: json
end

2 - 客户端:使用模板填充用户名称和图片

$('#typeahead').typeahead(null, {
  displayKey: 'name',
  source: bloodhound.ttAdapter()
  templates: {
    suggestion: Handlebars.compile('<p><img src="data:image/png;base64,{{base64}}">{{name}}</p>')
  }
});

注1:未经测试,您可能需要做一些调整

注意2:当您拥有大型用户表和大量并发连接时,这将需要服务器的大量电源,因为服务器必须为每个查询打开并编码许多图像文件。

答案 1 :(得分:2)

displayKey属性告诉Typeahead要显示 JSON响应的哪个(字符串)字段,因此它只能指向现有的JSON属性,例如name

我建议不要渲染图像,而是将其URL作为响应的一部分提供,然后在浏览器中呈现它。

例如,您可以为User模型添加新方法:

def thumb_url
  avatar.url(:thumb)
end

将该方法的结果添加到您的控制器的响应中:

def typeahead
  render json: User.where(name: params[:query]), methods: :thumb_url
end

然后在Typeahead template而不是displayKey中使用响应,例如

$('#typeahead').typeahead(null, {
  source: bloodhound.ttAdapter()
  templates: {
    suggestion: Handlebars.compile('<p><img src="{{thumb_url}}">{{name}}</p>')
  }
});

(请注意,您必须添加Handlebars才能生效。)