【问题标题】:Twitter typeahead no result when using “prefetch”, but working with “remote” JSONTwitter typeahead 使用“预取”时没有结果,但使用“远程”JSON
【发布时间】:2014-10-23 17:41:03
【问题描述】:

我整天都在挣扎。 我的 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数据格式正确。所有字符串(例如,在标记中)也用双引号引起来。 为什么远程数据有效但预取无效?

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

【问题讨论】:

    标签: jquery json bootstrap-typeahead twitter-typeahead


    【解决方案1】:

    除了正在设置的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 个项目(在这种情况下来自预取),则不需要访问服务器.

    sufficient – 如果内部搜索索引提供的数据数量不足,则远程将用于回填由调用#search 触发的搜索请求。默认为 5。

    此外,为了进行测试,您可以在站点的根目录中的磁盘上创建一个文件(我们称之为prefetchData.json),将您的 json 数据文本直接复制到您在问题中列出的该文件中,然后更改直接指向它的 url。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-06
      • 1970-01-01
      • 2014-12-25
      • 2016-04-03
      • 1970-01-01
      • 2013-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多