2017-04-26 21 views
1

提案と検索にTypeahead/Bloodhoundを使用しようとしています。わかりやすくするために、2種類のモデルオブジェクト()があるとします。TypeaheadとBloodhoundで複数のデータセットを一度に使用するにはどうすればよいですか?

public class Country 
{ 
    public string Name { get; set; } 
} 

(サーバー側はASP.NETですが、質問には関係ありません)。

市は、異なる名前を除いて、国と実質的に同じです。とにかく

、スタイリング前に、私は最終的な結果は次のようになりことを期待:

bloodhound multiple datasets

(それは明白でなければ、私は「AL」を書いたテキストボックスに、残りの文字を形成します最初の提案)

そして、私は複数のブラッドハウンドを使って、簡単にこれを達成することができるよ:

var countries = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    limit: 5, 
    remote: { 
     url: 'http://localhost:5000/api/countries/%QUERY', 
     wildcard: '%QUERY' 
    } 
}); 

var cities = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    limit: 5, 
    remote: { 
     url: 'http://localhost:5000/api/cities/%QUERY', 
     wildcard: '%QUERY' 
    } 
}); 

と複数の入力オブジェクト先読みする:

$('#remote .typeahead').typeahead(null, 
    { 
     name: 'countries', 
     display: 'name', 
     source: countries, 
     templates: { 
      empty: [ 
       '<div class="empty-message">', 
       'unable to find any countries that match the current query', 
       '</div>' 
      ].join('\n'), 
      suggestion: Handlebars.compile('<div><strong>{{name}}</strong></div>'), 
      header: '<h2>Countries</h2>' 
     } 

    }, 
    { 
     name: 'cities', 
     display: 'name', 
     source: cities, 
     templates: { 
      empty: [ 
       '<div class="empty-message">', 
       'unable to find any cities that match the current query', 
       '</div>' 
      ].join('\n'), 
      suggestion: Handlebars.compile('<div><strong>{{name}}</strong></div>'), 
      header: '<h2>Cities</h2>' 
     } 

    }); 

しかし、私の現実のシナリオでは、私は約10のデータセットを持っています。 JSONのシリアライゼーション/デシリアライゼーションと組み合わせた10個の別個のクエリを作成すると、おそらく複数のユーザがいる場合でも、その場で私のサーバが壊れる可能性があります。私が好む何

は、複合DTOを持つことです。

public class CompositeSearchResult 
{ 
    public List<Country> Countries { get; set; } 
    public List<City> Cities { get; set; } 
    //... and many others 
} 

...何とかブラッドハウンドとクライアント上の複雑なオブジェクトを処理中。これは可能ですか?

答えて

1

私はそれをしました!

最初に、Bloodhoundのキャッシュはスマートなので、すでに検索クエリが実行されていると、ネットワークを使用しなくなり、代わりにキャッシュが検索されます。

これは、両方のデータセットのURLが同じ場合、クエリはサーバー上で1回しか実行されず、結果セットがキャッシュされ、すべてのハートハウンドによって使用されることを意味します。

バックの単純な国+都市の例に行く、それは次のようになります。どちらの場合も

var countries = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    limit: 5, 
    remote: { 
     url: 'http://localhost:5000/api/compositesearch/%QUERY', 
     wildcard: '%QUERY', 
     transform: function(d) { 
      return d.countries; 
     } 
    } 
}); 

var cities = new Bloodhound({ 
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
    limit: 5, 
    remote: { 
     url: 'http://localhost:5000/api/compositesearch/%QUERY', 
     wildcard: '%QUERY', 
     transform: function(d) { 
      return d.cities; 
     } 
    } 
}); 

唯一の違いは、リモート設定で、「変換」機能です。

次に、質問とまったく同じCompositeSearchオブジェクトを使用して、ブラウザの[ネットワーク]タブで確認された2つのデータセット(スクリーンショットと基本的に同じ)を2つの代わりに取得できます。 )

関連する問題