20

アップデート

@BenSmith ( https://stackoverflow.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 オブジェクトがあります。Bloodhound が理解できるように、JSON オブジェクトをナビゲートする方法を見つけようとしています。

ここでの目標は、ユーザーが曲名を入力し始めることです。オートコンプリートは、曲名とそれが演奏されたアーティストのリストを表示します。

例:マストドンによる真夜中のチャイム

各ライブラリの最新バージョンを使用しています: 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"}, {"catalog": "7digital-UK", "foreign_id": "7digital-UK:artist:29785"}], "tracks": [], "artist_id": "ARMQHX71187B9890D3", "id": "SOKSFNN1463B7E4B1E"}, {"title": "Down Under", "artist_name": "Men at Work", "artist_foreign_ids": [{"catalog": "7digital-AU", "foreign_id": "7digital-AU: アーティスト: 50611"}]、"トラック": []、"artist_id": "AR4MVC71187B9AEAB3"、"id": "SORNNEB133A920BF86"}]}}

このサイトhttp://json.parser.online.fr/を使用して、JSON を簡単にフォーマットします。

返される JSON は常に同じ形式ですが、異なるデータが含まれています。この例では、「トラック」は null です。他の結果にはデータがあります。また、そのデータにもアクセスできる必要があります。

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

このコードを実行しようとすると、次のエラーが発生します。

キャッチされていない TypeError: 未定義のプロパティ 'トークン' を読み取ることができません

ここでの助けや指示は大歓迎です。Typeahead/Bloodhound で作業している JSON データを取得する方法を知る必要があるだけです。

ありがとう!

4

2 に答える 2

11

私の答えは新しいものではなく、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'
    });

変化したこと:

  1. filterの下にオプションはありませんprefetch。代わりに を使用する必要がありますtransform
  2. displayKey下のtypeahead()機能は単に に変更されましたdisplay
  3. cachetransformデータソースが毎回ロードされるように、オプションの下に false が設定されています。これはテストには適していますが、実稼働サーバーでデータのキャッシュが必要な場合は、このオプションを無効にする必要があります。

cachetrue に設定されたさまざまなデータ ソースでこの例を試している人への追加のメモとして。window.localStorage.clear();新しいデータを取得できるように、常にコンソールでメソッドを実行して、既存のローカル ストレージをクリアする必要 があります。そうしないと、古いデータが使用されることになり、コードが機能しない理由を考えるかもしれません。

これは、作業を開始するための実際のJSFIDDLEの例です。いくつかの注意点:

  1. 先行入力用の CDN があるかどうかわからなかったので、単純に先行入力の 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"}]
于 2016-01-02T07:38:47.190 に答える