2015-11-16 24 views
6

meteor search-sourcethisチュートリアルに続き、私の現在のニーズに合うようにこの例を修正しました。 これは私が私のクライアント側のコントローラのコードを次しているMeteor検索ソースパッケージを使用しようとすると、エラーが発生するのはなぜですか?

Guides = new Mongo.Collection("guides"); 

私のlibディレクトリにあります。私のcollections.jsです。何らかの理由で

var options = { 
    keepHistory: 1000 * 60 * 5, 
    localSearch: true 
}; 

var fields = ['title']; 

GuideSearch = new SearchSource('guides', fields, options); 

Template.guide_list.helpers({ 
    getGuides: function() { 
     return GuideSearch.getData({ 
      transform: function (matchText, regExp) { 
       return matchText.replace(regExp, "<b>$&</b>") 
      } 
     }); 
    }, 

    isLoading: function() { 
     return GuideSearch.getStatus().loading; 
    } 
}); 


Template.guide_list.events({ 
    "keyup #title": _.throttle(function(e) { 
     var text = $(e.target).val().trim(); 
     GuideSearch.search(text); 
    }, 200) 
}); 
私のサーバー側のコードとして

そしてこの

SearchSource.defineSource('guides', function(searchText, options) { 
    if(searchText) { 
    var regExp = buildRegExp(searchText); 
    var selector = {title: regExp} 
    return Guides.find(selector, options).fetch(); 
    } else { 
    return Guides.find({}, options).fetch(); 
    } 
}); 

function buildRegExp(searchText) { 
    // this is a dumb implementation 
    var parts = searchText.trim().split(/[ \-\:]+/); 
    return new RegExp("(" + parts.join('|') + ")", "ig"); 
} 

Exception in delivering result of invoking 'search.source': Meteor.makeErrorType/[email protected]://10.0.3.162:3000/packages/meteor.js?9730f4ff059088b3f7f14c0672d155218a1802d4:525:15 
[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:4625:23 
Connection/[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:3365:7 
._launchConnection/self.socket.onmessage/<@http://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2734:11 
[email protected]://10.0.3.162:3000/packages/underscore.js?46eaedbdeb6e71c82af1b16f51c7da4127d6f285:149:7 
._launchConnection/[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2733:9 
[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:173:9 
[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1158:5 
[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1216:13 
SockJS.websocket/[email protected]://10.0.3.162:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1363:9 

私の入力フィールドに何かを入力するとき、私は次のエラーメッセージが表示されるこれは私のテンプレートコードです:

template(name="guide_list") 
    .format-properly 
     .container-fluid 
      .input-group#adv-search 
       .form-horizontal(role="form" method="POST" action="#") 
        .col-md-6 
         .form-group 
          label(for="contain") Guide title 
          input.form-control(type="text" id="title") 
        .col-md-6 
         .form-group 
          label(for="contain") Author 
          input.form-control(type="text" name="author") 
        .col-md-6 
         .form-group 
          label(for="hero") Select a hero 
          select.form-control(name="hero") 
           option(value="all" selected) All Heroes 
           option(value="Druid") Druid 
           option(value="Hunter") Hunter 
           option(value="Mage") Mage 
           option(value="Paladin") Paladin 
           option(value="Priest") Priest 
           option(value="Rogue") Rogue 
           option(value="Shaman") Shaman 
           option(value="Warlock") Warlock 
           option(value="Warrior") Warrior 
        .col-md-6 
         .form-group 
          label(for="filter") Filter by 
          select.form-control(name="filterBy") 
           option(value="0" selected) All guides 
           option(value="most_viewed") Most viewed 
           option(value="top_rated") Top rated 
           option(value="most_commented") Most commented 

     .container-fluid 
      .table-responsive 
       table.table.table-hover 
        thead 
         tr 
          th hero 
          th title 
          th author 
          th updated 
          th dust 
          th 
           span.glyphicon.glyphicon-eye-open 
          th 
           span.glyphicon.glyphicon-heart 
          th 
           span.glyphicon.glyphicon-comment 
        tbody 
         each guides 
          tr 
           td {{hero}} 
           td 
            a(href="/guide/{{formatId _id}}") {{title}} 
           td {{authorUsername}} 
           td {{moFormat modifiedAt 'YYYY-MM-DD'}} 
           td {{dust}} 
           td {{hitCount}} 
           td {{rating}} 
           td {{commentCount}} 

        tbody 
         each getGuides 
          tr 
           td {{hero}} 
           td 
            a(href="/guide/{{formatId _id}}") {{title}} 
           td {{authorUsername}} 
           td {{moFormat modifiedAt 'YYYY-MM-DD'}} 
           td {{dust}} 
           td {{hitCount}} 
           td {{rating}} 
           td {{commentCount}} 

何か助けや提案をいただければ幸いです。

編集:私は問題がGuideSearch.searchメソッドに渡されたoptionsの不足であることを信じ1.4.2

+0

'ガイドは=新しいMongo.Collection(「ガイド」);'で定義されていますクライアントサイドスクリプト。 'Guides'もサーバーサイドスクリプトで呼び出されていますが、クライアントスクリプトで定義されているため利用できません。そのコード行を 'lib'フォルダ内のjsファイルに移動してください。そうすれば、サーバとクライアントの両方で利用できるようになります。そうでない場合は、テンプレートからHTMLを含めることができます。 –

+0

@BrianShamblenコレクションの宣言は誤りではありませんでした。しかし、私は自分の投稿を編集してテンプレートを投稿しました:) –

+0

これは私が私の答えで言及した(文書化されていない)問題によるものだと思います。そうでない場合は、サーバーログにエラーがないかどうかを確認します。このパッケージは少しの愛と更新が必要です:) – MasterAM

答えて

3

からsearch-sourceパッケージを更新しました。

これにより、検索定義ハンドラがオプションとしてnullになります。

SearchSource.defineSource('guides', function(searchText, options) { 
    if(searchText) { 
    var regExp = buildRegExp(searchText); 
    var selector = {title: regExp} 
    return Guides.find(selector, options).fetch(); //illegal 
    } else { 
    return Guides.find({}, options).fetch(); 
    } 
}); 

これは、提供されている場合、オブジェクト(およびないnull)でなければならないことを、ヌルoptions引数を取得し、コレクションのfind()方法になります。したがって

、いずれかのデータソースにヌルoptionsをチェックしfind()メソッドに空のオブジェクト(または何も)を渡す、またはGuideSearch.search()メソッドに空のオブジェクトを渡す:

Template.guide_list.events({ 
    "keyup #title": _.throttle(function(e) { 
     var text = $(e.target).val().trim(); 
     GuideSearch.search(text, {}); // here 
    }, 200) 
}); 

あなたがすべきでしょういずれにしても、@ webdebの答えのように、optionsがサーバメソッドでnullでないことを確認してください。

さらに、meteorhacks:search-sourceパッケージで依存関係を宣言することなくアプリケーションに依存するパッケージ(checkおよびejson)を追加する必要があります。これはv1.2.0で導入された変更によるものです。 (それ以前は、これらのシンボルはパッケージで自動的に利用可能でした)。

最初にすべての結果を利用できるようにするために、テンプレートが最初に作成されたときに検索をトリガーすることができます。 大量のデータがある場合、これはかなりコストがかかる可能性があるので、おそらくサーバー上の検索定義ハンドラから返される結果を制限する必要があります。

Template.guide_list.onCreated(function() { 
    GuideSearch.search('', {}); 
}); 

炎がHTMLとしてレンダリングするために知っているように、検索結果に正しくタイトルを表示するためには、Spacebars.SafeString()を使用することができます。

Template.guide_list.helpers({ 
    getGuides: function() { 
     return GuideSearch.getData({ 
      transform: function (matchText, regExp) { 
       return Spacebars.SafeString(matchText.replace(regExp, "<b>$&</b>")) 
      } 
     }); 
    }, 
    formatId: function(id) { 
     return id; 
    }, 
    moFormat: function(date, format) { 
     return moment(date).format(format); 
    }, 
    isLoading: function() { 
     return GuideSearch.getStatus().loading; 
    } 
}); 

Template.guide_list.events({ 
    "keyup #title": _.throttle(function(e) { 
     var text = $(e.target).val().trim(); 
     GuideSearch.search(text, {/* your options here */}); 
    }, 200) 
}); 

、あるいは、トリプルブレース表記を使用します。警告

a(href="/guide/{{formatId _id}}") {{{title}}} 

を:これを行うときにmatchTextをサニタイズするようにしてください。

パブリケーションは、パッケージが独自のコレクションを使用するため、結果と関係がありません。

+1

私は興味があります。私は私のマシン上に働いているバージョンを持っています。私がしなければならなかったのは、 'check'と' ejson'を追加することだけです。パッケージは依存関係を宣言することなくそれらを使います(v1.2.0以前と同じように自動的に利用できないので)サーバー上の 'Guides.find()'に 'null 'ではありませんでした。 – MasterAM

+0

あなたは男です!今はcharm =)のように動作します! 'check'と' ejson'パッケージを追加するだけでした。私のテンプレートを最初にレンダリングすると、そこに結果はありません。フィールドを検索するときに表示されます。ユーザーが何かを検索する前に、最初に利用可能なすべてのエントリを表示するにはどうしますか? –

+1

それを聞いてうれしいです。私はいくつかの小さな問題を始めて解決するためにいくつかの説明を追加しました。 – MasterAM

1

私は@MasterAMからの回答に同意するが、ちょうどあなたのSearchSource機能でこれを入れて、この問題を解決するために:

SearchSource.defineSource('guides', function(searchText, options) { 
    options = options || {}; // to be sure, that options is at least an empty object 
    if(searchText) { 
    var regExp = buildRegExp(searchText); 
    ... 
関連する問題