我整天都在苦苦挣扎。 我的先行搜索表达式与远程json数据完美配合。 但是当我尝试使用与预取数据相同的json数据时,建议是空的。在点击第一个符号后,我得到预定义的消息“无法找到任何东西...”以获得空结果。
这是我的剧本:
function initialTypeaheadTest(){
var mo_selector = $('*[data-moT="mysearch"]');
var engine = new Bloodhound({
limit: 10
,prefetch: {url:'/api/action/getjsontest'}
//,remote: {url:'/api/action/getjsontest'}
,datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name')
,queryTokenizer: Bloodhound.tokenizers.whitespace
});
engine.clearPrefetchCache(); // only for test purposes
engine.initialize();
mo_selector.typeahead(
{
hint: true,
highlight: true,
minLength: 1
}, {
name: 'engine',
displayKey: 'name',
source: engine.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'unable to find anything that match the current query',
'</div>'
].join('\n'),
suggestion: Handlebars.compile([
'<div id="{{value}}"><p style="max-height:100%;"><strong>{{title}}</strong></p>',
'<span style="font-size:12px;">{{year}}</span></div>'
].join(''))
}
});
}
那就是我的json:
[{
"year":"02 Feb 2013 at 00:40 by anonymous",
"title":"JavaScript HTML DOM Changing HTML Content",
"value":"1",
"tokens":["JavaScript", "HTML", "DOM", "Changing", "HTML", "Content"]
},{
"year":"02 Feb 2013 at 00:42 by anonymous",
"title":"WDR.de",
"value":"2",
"tokens":["WDR.de"]
},{
"year":"02 Feb 2013 at 00:46 by anonymous",
"title":"Nachrichten, aktuelle Schlagzeilen und Videos - n-tv.de",
"value":"3",
"tokens":["Nachrichten", "aktuelle", "Schlagzeilen", "und", "Videos", "n", "tv.de"]
},{
"year":"02 Feb 2013 at 00:55 by anonymous",
"title":"JavaScript RegExp Object",
"value":"5",
"tokens":["JavaScript", "RegExp", "Object"]
},{
"year":"15 Feb 2013 at 23:24 by anonymous",
"title":"DotnetNuke Module Car Listing Module",
"value":"8",
"tokens":["DotnetNuke", "Module", "Car", "Listing", "Module"]
},{
"year":"08 Feb 2014 at 01:08 by advertiser",
"title":"Empfehlung",
"value":"1000",
"tokens":["Empfehlung"]
}]
原始路径:mattopen.com/api/action/getjsontest
对我来说,一切看起来都不错。 json数据形成良好。所有字符串(例如在标记中)也用双引号引用。 为什么远程数据有效但预取不是? 有人能指出我正确的方向吗? 感谢答案 0 :(得分:6)
设置中的所有内容都很好,但正在设置的tokenizer
除外。因为要在数据数组中返回json对象类型,所以必须指定要标记化的json对象中的属性/字段。在您的代码中指定name
,但您的json类型不包含name
。如果您将其从name
更改为title
,一切都会按预期工作,然后会搜索title
字段。
更改行:
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name')
要:
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title')
这假设您要使用title
字段作为搜索索引。如果您希望搜索其他字段/属性,请将其更改为数组中列出的对象类型中存在的该字段/属性的名称。
如果要使用在对象中提供的标记,可以通过提供完全相同的功能来实现。将行datumTokenizer
替换为:
,datumTokenizer: function (yourObj) {
return yourObj.tokens; // returns the tokens array in your object
}
顺便说一句,默认Bloodhound.tokenizers.obj.whitespace
意味着它将尝试拆分带有空格的字符串。这也是你在上一个令牌实现中没有看到它的原因,因为我假设你的tokens
字段总是有你想要的整个字符串。
datumTokenizer - 具有签名(datum)的函数,用于将数据转换为字符串标记数组。必需的。
我还添加了sufficient
并将其设置为1,这告诉引擎如果至少返回了1个项目(在这种情况下是来自预取)那么前往服务器的是没必要。
足够 - 如果内部搜索索引提供的基准数量不足,则远程将用于回填通过调用#search触发的搜索请求。默认为5。
此外,为了进行测试,您可以在站点的根目录中的磁盘上创建一个文件(让我们称之为prefetchData.json
),将您的json数据文本直接复制到您在问题中列出的文件中,并且然后更改网址直接指向它。
prefetch: {url:'/prefetchData.json'}
以下是完整的工作代码,其中包含上述更改。现在,如果您输入J
,则应返回2个结果。
function initialTypeaheadTest(){
var mo_selector = $('*[data-moT="mysearch"]');
var engine = new Bloodhound({
limit: 10
,sufficient:1
,prefetch: {url:'/prefetchData.json'}
//,remote: {url:'/api/action/getjsontest'} // left it commented out to prove it works
,datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title')
,queryTokenizer: Bloodhound.tokenizers.whitespace
});
engine.clearPrefetchCache(); // only for test purposes
engine.initialize();
mo_selector.typeahead(
{
hint: true,
highlight: true,
minLength: 1
}, {
name: 'engine',
displayKey: 'name',
source: engine.ttAdapter(),
templates: {
empty: [
'<div class="empty-message">',
'unable to find anything that match the current query',
'</div>'
].join('\n'),
suggestion: Handlebars.compile([
'<div id="{{value}}"><p style="max-height:100%;"><strong>{{title}}</strong></p>',
'<span style="font-size:12px;">{{year}}</span></div>'
].join(''))
}
});
}