首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Typeahead v0.10.2和Bloodhound - 如何使用嵌套的JSON对象?

Typeahead v0.10.2和Bloodhound - 如何使用嵌套的JSON对象?
EN

Stack Overflow用户
提问于 2018-03-29 23:51:52
回答 2查看 0关注 0票数 0

没有正确导航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>')
          }
      });

原始问题

我是与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”},{“catalogue:”7digital-UK“, “foreign_id”:“7digital-UK:artist:29785”}],“tracks”:[],“artist_id”:“ARMQHX71187B9890D3”,“id”:“SOKSFNN1463B7E4B1E”},{“title”:“Down Down” “artist_name”:“男人在工作中”,“artist_foreign_ids”:[{“catalog”:“7digital-AU”,“foreign_id”:“7digital-AU:artist:50611“}],”tracks“:[],”artist_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()
      });

当我尝试运行此代码时,出现以下错误:

Uncaught TypeError: Cannot read property 'tokens' of undefined

任何帮助或方向在这里将不胜感激。我只需要知道如何获得我正在与Typeahead / Bloodhound合作的JSON数据。

EN

回答 2

Stack Overflow用户

发布于 2018-03-30 08:10:36

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

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

(可以在这里找到过滤功能的例子)

然后将数据管理器更改为:

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

还要将显示键更改为:

displayKey: 'title'

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

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

suggestion: Handlebars.compile('<p><strong>{{title}}</strong> by {{artistName}}</p>')
票数 0
EN

Stack Overflow用户

发布于 2018-03-30 09:06:55

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

对于仍在使用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'
    });

什么改变了:

  1. filter下没有选择prefetch。相反,你必须使用transform
  2. displayKeytypeahead()功能下已经改变为简单display
  3. cachetransform选项下设置为false,以便每次加载数据源。这对测试非常有用,但在生产服务器中,如果需要缓存数据,则必须禁用此选项。

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

这是一个可用的JSFIDDLE示例,以帮助开始。有几点需要注意:

  1. 我不知道是否有类型为CDN的CDN,所以我只是将整个typeahead JavaScript代码粘贴在那里。在页面的底部,你可以看看我的功能。
  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"}]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档