更新
基于@BenSmith(https://stackoverflow.com/users/203371/BenSmith)的正确答案,我能够找到问题并发现我没有正确浏览我的JSON层次结构。这是工作代码:
// instantiate the bloodhound suggestion engine
var engine = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.title);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: "SampleData.json",
filter: function (data) {
//console.log("data", data.response.songs)
return $.map(data.response.songs, function (song) {
return {
title: song.title,
artistName: song.artist_name
};
});
}
}
});
// initialize the bloodhound suggestion engine
engine.initialize();
// instantiate the typeahead UI
$('#prefetch .typeahead').typeahead(
{
hint: true,
highlight: true,
minLength: 1
},
{
name: 'engine',
displayKey: 'title',
source: engine.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'unable to find any results that match the current query',
'</div>'
].join('\n'),
suggestion: Handlebars.compile('<p><strong>{{title}}</strong> by {{artistName}}</p>')
}
});
感谢@BenSmith的帮助!
原始问题
我是使用Typeahead和Bloodhound的新手。文档不是很有帮助。我有一组JSON对象,我从我正在使用的API中获取。我试图弄清楚如何浏览我的JSON对象,以便Bloodhound可以理解它们。
此处的目标是用户将开始输入歌曲名称。然后,自动完成功能将显示歌曲名称列表及其执行的艺术家。
例如:Mastodon午夜的 Chimes
我正在使用每个库的最新版本: https://twitter.github.io/typeahead.js/
示例JSON(SampleData.json):
{"response": {"status": {"version": "4.2", "code": 0, "message": "Success"}, "songs": [{"title": "Chimes At Midnight", "artist_name": "Mastodon", "artist_foreign_ids": [{"catalog": "7digital-AU", "foreign_id": "7digital-AU:artist:29785"}, {"catalog": "7digital-UK", "foreign_id": "7digital-UK:artist:29785"}], "tracks": [], "artist_id": "ARMQHX71187B9890D3", "id": "SOKSFNN1463B7E4B1E"}, {"title": "Down Under", "artist_name": "Men at Work", "artist_foreign_ids": [{"catalog": "7digital-AU", "foreign_id": "7digital-AU:artist:50611"}], "tracks": [], "artist_id": "AR4MVC71187B9AEAB3", "id": "SORNNEB133A920BF86"}]}}
使用此网站http://json.parser.online.fr/轻松格式化JSON。
我将返回的JSON将始终采用相同的格式,但包含不同的数据。在此示例中,“轨道”为空。其他结果将有数据。我还需要能够访问这些数据。
我正在使用最新版本的JQuery。这是我在html页面中包含的内容:
<script src="Scripts/jquery-2.1.1.min.js"></script>
<script src="Scripts/typeahead.bundle.min.js"></script>
这是HTML:
<div id="prefetch">
<input class="typeahead" type="text" placeholder="Songs...">
</div>
这是脚本:
// instantiate the bloodhound suggestion engine
var engine = new Bloodhound({
datumTokenizer: function (d) { return Bloodhound.tokenizers.whitespace(d.tokens.join(' ')); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: "SampleData.json",
filter: function (response) {
return response.engine;
}
}
});
// initialize the bloodhound suggestion engine
engine.initialize();
// instantiate the typeahead UI
$('#prefetch .typeahead').typeahead(
{
hint: true,
highlight: true,
minLength: 1
},
{
name: 'songs',
displayKey: function (engine) {
return engine.songs.artist_name;
},
source: engine.ttAdapter()
});
当我尝试运行此代码时,出现以下错误:
未捕获的TypeError:无法读取未定义的属性'标记'
非常感谢任何帮助或方向。我只需要知道如何获取我正在使用Typeahead / Bloodhound的JSON数据。
谢谢!
答案 0 :(得分:20)
您需要编写过滤器函数,以便创建一个javascript对象数组以用作基准。以下应该有效(我还没有对此进行测试):
filter: function (response) {
return $.map(response.songs, function (song) {
return {
title: song.title,
artistName: song.artist_name
};
});
}
(可以找到过滤器功能的示例here)
将您的datumtokenizer更改为:
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.title);
}
还将您的显示键更改为:
displayKey: 'title'
因为这是Typeahead将用于搜索的关键。
至于在推荐列表中显示歌曲名称和艺术家,我建议您使用模板(例如Handlebars)来显示结果。请参阅&#34;自定义模板&#34; Typeahead's examples page中的示例。您的建议标记将类似于以下内容:
suggestion: Handlebars.compile('<p><strong>{{title}}</strong> by {{artistName}}</p>')
答案 1 :(得分:11)
我的回答并不新鲜,只是twitter类型的v0.11的更新。与往常一样,将您的upvotes(如果有)重定向到原始答案。
友情提醒所有仍在使用Twitter-Typeahead的人 是因为它不再被维护而离开这个存储库。 而是将自己重定向到corejavascript/typeahead.js 原始存储库的一个分支,和同一个作者(@JakeHarding) 维护这个存储库。
从v0.10到v0.11,一些事情发生了变化,答案也必须如此。这是我对这个新版本的新代码。
<强> HTML 强>
<div id="prefetch">
<input class="typeahead" type="text" placeholder="Countries">
</div>
<强> JS 强>
var tags = new Bloodhound({
datumTokenizer: function(datum) {
return Bloodhound.tokenizers.whitespace(datum.name);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'http://www.yourwebsite.com/js/data.json',
cache: false,
transform: function(response) {
return $.map(response, function (tag) {
return {
name: tag.tagName,
id: tag.tagId
}
});
}
}
});
$('#prefetch .typeahead').typeahead({
minLength: 3,
highlight: true
}, {
name: 'tags-dataset',
source: tags,
display: 'name'
});
发生了什么变化:
filter
下没有prefetch
选项。相反,您必须使用transform
。displayKey
功能下的typeahead()
已更改为display
。cache
选项下的transform
设置为false,以便每次都加载数据源。这适用于测试,但在生产服务器中,如果需要缓存数据,则必须禁用此选项。作为对尝试此示例的人们的补充说明
cache
设置为true的不同数据源。你必须经常跑 您的控制台中的window.localStorage.clear();
方法可以清除 已经存在本地存储,以便可以检索新数据。 如果不这样做将导致使用旧数据,您可能会这样做 想想为什么你的代码不起作用。
这是一个有效的JSFIDDLE示例,可帮助您入门。需要注意几点:
[{"tagId":9,"tagName":"Action"},{"tagId":10,"tagName":"Adventure"},{"tagId":6,"tagName":"Books"},{"tagId":11,"tagName":"Fantasy"},{"tagId":2,"tagName":"Games"},{"tagId":1,"tagName":"Movies"},{"tagId":3,"tagName":"Music"},{"tagId":8,"tagName":"News"},{"tagId":4,"tagName":"Office"},{"tagId":5,"tagName":"Security"},{"tagId":7,"tagName":"TV-Shows"}]