Typeahead v0.10.2 和 Bloodhound - 使用嵌套的 JSON 对象
Posted
技术标签:
【中文标题】Typeahead v0.10.2 和 Bloodhound - 使用嵌套的 JSON 对象【英文标题】:Typeahead v0.10.2 & Bloodhound - Working With Nested JSON Objects 【发布时间】:2014-08-24 22:55:59 【问题描述】:更新
根据@bensmith的正确答案(https://***.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 的新手。该文档不是很有帮助。我有一组从我正在使用的 API 返回的 JSON 对象。我正在尝试弄清楚如何浏览我的 JSON 对象,以便 Bloodhound 能够理解它们。
这里的目标是用户将开始输入歌曲名称。然后,自动完成将显示歌曲名称列表和演唱者。
例如:Mastodon 的午夜钟声
我正在使用每个库的最新版本: https://twitter.github.io/typeahead.js/
示例 JSON (SampleData.json):
“响应”:“状态”:“版本”:“4.2”,“代码”:0,“消息”:“成功”,“歌曲”:[“标题”:“午夜钟声”, “artist_name”:“mastodon”,“artist_foreign_ids”:[“目录”:“7digital-au”,“fignd_id”:“7digital-au:艺术家:29785”,“目录”:“7digital-UK”, “figner_id”:“7digital-UK:艺术家:29785”“,”曲目“:[],”ARTIST_ID“:”ARMQHX71187B9890D3“,”ID“:”SOKSFNN1463B7E4B1E“,”标题“:”下降“, “artist_name”:“working的男人”,“artist_foreign_ids”:[“目录”:“7digital-au”,“fignd_id”:“7digital-au:艺术家:50611”“,”曲目“:[],”艺术家 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()
);
当我尝试运行此代码时,我收到以下错误:
未捕获的类型错误:无法读取未定义的属性“令牌”
这里的任何帮助或指导将不胜感激。我只需要知道如何使用 Typeahead/Bloodhound 获取我正在使用的 JSON 数据。
谢谢!
【问题讨论】:
很高兴我能帮助 Jared :) 【参考方案1】:您需要编写过滤器函数,以便它创建一个 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)来显示结果。请参阅Typeahead's examples page 中的“自定义模板”示例。然后,您的建议标记将类似于以下内容:
suggestion: Handlebars.compile('<p><strong>title</strong> by artistName</p>')
【讨论】:
您好,非常感谢您提供的这个非常好的答案!它真的帮助我更好地理解了这一点。我已经实现了代码,没有更多的错误。不过我还是有问题。当我尝试搜索歌曲名称时,会出现我的“空”模板消息。出于某种原因,当我输入歌曲名称时,它无法找到它们。为了简单起见,我在这里创建了一个 JSFiddle:jsfiddle.net/VBLTS/2 忘了提这个。我收到这个 JS 错误:未捕获的类型错误:无法读取未定义的属性“长度” 我发现了问题。我没有正确浏览 JSON。我正在调用 response.songs,而它确实需要基于我的 JSON 结构的 response.response.songs。所以我将函数重命名为 data,现在调用 data.response.songs 一切正常。 @user993514 在我的手机上看到了你的评论,但现在才有机会在我的电脑上帮助你。好消息,您的应用程序已正常运行,我很高兴能提供帮助 :)【参考方案2】:我的回答并不新鲜,只是 twitter typeahead v0.11 的更新。与往常一样,将您的赞成票(如果有)重定向到原始答案。
对仍在使用 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'
);
发生了什么变化:
prefetch
下没有filter
选项。相反,您必须使用transform
。
typeahead()
函数下的 displayKey
已更改为简单的 display
。
将transform
选项下的cache
设置为false,以便每次都加载数据源。这有利于测试,但在生产服务器中,如果需要缓存数据,则必须禁用此选项。
作为对尝试此示例的人们的补充说明
cache
设置为 true 的不同数据源。您必须始终运行window.localStorage.clear();
方法在您的控制台中清除 已经存在本地存储,以便可以检索新数据。 否则将导致使用旧数据,您可能 想想为什么你的代码不工作。
这是一个有效的 JSFIDDLE 示例,可帮助您入门。需要注意的几点:
-
我不知道是否有用于预先输入的 CDN,所以我只是将整个预先输入的 JavaScript 代码粘贴在那里。在页面底部,您可以查看我的功能。
数据源指向一个链接,该链接是托管在我的 Dropbox 帐户中的文件。如果我删除了这个文件,这个例子根本不起作用。因此,您需要提供自己的来源。这是该文件的内容 -
["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"]
【讨论】:
不错的 Rash 更新,感谢您让我了解 corejavascript/typeahead.js!以上是关于Typeahead v0.10.2 和 Bloodhound - 使用嵌套的 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章
在 Bootstrap 3 中使用 tagsinput 和 typeahead