Typeahead v0.10.2&Bloodhound – 使用嵌套的JSON对象

UPDATE

根据@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: [ '
', 'unable to find any results that match the current query', '
' ].join('\n'), suggestion: Handlebars.compile('

{{title}} by {{artistName}}

') } });

谢谢@BenSmith的帮助!


原始问题

我是使用Typeahead和Bloodhound的新手。 文档不是很有帮助。 我有一组JSON对象,我从我正在使用的API中获取。 我试图弄清楚如何浏览我的JSON对象,以便Bloodhound可以理解它们。

这里的目标是用户将开始键入歌曲名称。 然后,自动完成将显示歌曲名称列表和由其执行的艺术家。

例如: Mastodon在午夜编钟

我正在使用每个库的最新版本: 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:艺术家:29785”},“track”:[],“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”}],“track”:[],“ artist_id“:”AR4MVC71187B9AEAB3“,”id“:”SORNNEB133A920BF86“}]}}

使用此站点http://json.parser.online.fr/可以轻松地格式化JSON。

我将返回的JSON将始终采用相同的格式,但包含不同的数据。 在此示例中,“轨道”为空。 其他结果将有数据。 我还需要能够访问该数据。

我正在使用最新版本的JQuery。 这是我在html页面中包含的内容:

   

这是HTML:

 

这是脚本:

  // 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数据。

谢谢!

您需要编写filter函数,以便创建一个javascript对象数组以用作基准。 以下应该工作(我没有测试过):

 filter: function (response) { return $.map(response.songs, function (song) { return { title: song.title, artistName: song.artist_name }; }); } 

(可在此处找到过滤function的示例)

并将您的datumtokenizer更改为:

 datumTokenizer: function (datum) { return Bloodhound.tokenizers.whitespace(datum.title); } 

还将displaykey更改为:

 displayKey: 'title' 

因为这是Typeahead将用于搜索的关键。

至于在建议列表中显示歌曲名称和艺术家,我建议你使用模板(例如Handlebars)来显示结果。 请参阅Typeahead的示例页面中的“自定义模板”示例。 您的建议标记将类似于以下内容:

 suggestion: Handlebars.compile('

{{title}} by {{artistName}}

')

我的回答并不新鲜,只是twitter类型的v0.11的更新。 与往常一样,将您的upvotes(如果有)重定向到原始答案。

对仍在使用Twitter-Typeahead的每个人的友好提醒是,因为它不再被维护而离开此存储库。 而是将自己重定向到corejavascript / typeahead.js ,它是原始存储库的一个分支,同一作者(@JakeHarding)维护此存储库。

从v0.10到v0.11,一些事情发生了变化,答案也必须如此。 这是我对这个新版本的新代码。

HTML

 

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' }); 

发生了什么变化:

  1. prefetch没有filter选项。 相反,你必须使用transform
  2. displayKey typeahead()函数下的displayKey已更改为简单display
  3. cache under transform选项设置为false,以便每次都加载数据源。 这适用于测试,但在生产服务器中,如果需要缓存数据,则必须禁用此选项。

作为对使用cache设置为true的不同数据源尝试此示例的人员的补充说明。 你必须始终运行window.localStorage.clear(); 控制台中的方法可以清除已存在的本地存储,以便可以检索新数据。 如果不这样做将导致使用旧数据,您可能会认为代码无法正常工作。

这是一个有效的JSFIDDLE示例,可帮助您入门。 几点需要注意:

  1. 我不知道是否有针对typeahead的CDN,所以我只是将整个类型的javascript代码粘贴在那里。 在页面底部,您可以查看我的function。
  2. 数据源指向链接,该链接是我的保管箱帐户中托管的文件。 如果我删除此文件,此示例根本不起作用。 因此,您需要提供自己的来源。 以下是该文件的内容 – [{"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"}]