Twitter使用“prefetch”时没有结果,但使用“远程”JSON

时间:2014-10-23 17:41:03

标签: jquery json bootstrap-typeahead twitter-typeahead

我整天都在苦苦挣扎。 我的先行搜索表达式与远程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数据形成良好。所有字符串(例如在标记中)也用双引号引用。 为什么远程数据有效但预取不是?

有人能指出我正确的方向吗? 感谢

1 个答案:

答案 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字段总是有你想要的整个字符串。

来自Bloodhound Documentation

  

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(''))
            }
    });
}
相关问题