我使用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)
在其他地方成功显示]
答案 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才能生效。)