2017-04-21 6 views
1

これは、リアクティブvarsを含む動的クエリと、リアクティブvars値が変更されたときに再実行されない$ where演算子を含むヘルパーの問題です。次に、それを解決しようとすると、奇妙なシステムの動作とクラッシュにつながります。ダイナミックで何とか精巧でTasksコレクション内のドキュメントのための非反応ヘルパーとテンプレート#それぞれがクラッシュする

<template name="todo"> 
    {{#each pendingMTs}} 
     <button class="showPendMT"> 
      <h4> - <strong> {{name}}</strong> </h4> 
     </button> 
    {{/each}} 
</template> 

pendingMTsヘルパーを検索:

は、私たちは#eachループ内に挿入された文書のリストを表示したいテンプレートを持っています

:検索に関与

pendingMTs() { 
    return Tasks.find( 
     { $and: [ { owner: Meteor.userId() }, 
        { time: { $gt: 0 } },  
        { $where: function() 
{ return moment(this.createdAt).add((((this.timeuts == 'Days') ? 1 : ((this.timeuts=='Meses') ? 30 : 365)) * this.time), 'days').diff(moment([currYear.get(), currMonth.get()])) < 0; }} 
       ] 
     }); 
} 

二つの反応VARSは、テンプレートの作成時に定義されています:オペレーターが$を使用することを含むsimplified-クエリを-here

Template.todo.onCreated(function() { 
    var year = moment().format("YYYY"); 
    var month = moment().format("M"); 
    month = month - 1; //to values from 0 to 11 

    currYear = new ReactiveVar(year); 
    currMonth = new ReactiveVar(month); 
}); 

そして、イベントハンドラで我々はcurrMonthのために、たとえば、「選択」変化に反応VARSを変更します。

'change #monthForecast' (event) { 
    event.preventDefault(); 
    const target = event.target; 
    currMonth.set(target.value); 
}, 

最初の問題は、我々はを通じて変更にもかかわらず、ヘルパーが再実行されていないということですイベントハンドラリアクションバーの値:WHY ??

:これは反応性VARSは機能、私は単にヘルパーで彼らのために意識を作成するために、ヘルパーの先頭にシンプルなラインを追加しました$の内側にあるという事実によるかもしれないと考える

var rerun = currYear.get(); rerun = currMonth.get(); 

確かに、2つの反応性の変数のいずれかが変更されたときにいつでもヘルパーに再実行させました。しかし、残念ながら非常に奇妙な行動に、このリード:

  • 反応VARSが変更されたが、ヘルパーによって取得された文書に影響を与えなかった場合は、システムが正常に実行されているが、された:
  • すると修正に反応VARS文書の数より1つの多いドキュメントを取得するためのヘルパーは最初の時間を取得し、システムがクラッシュした(したがって、新しいドキュメントが#eachテンプレートに示されていなかった)原因:

    Exception from Tracker recompute function: meteor.js:930:11 
    Error: Bad index in range.getMember: 3 
    

原因を探しているうちに、悪いインデックス番号(この場合は3)は、ヘルパーが初めて実行されたときに取得されたドキュメントの数と常に等しいことがわかりました。この場合、リアクションバーの1つの値を変更した後、システムクラッシュ時に4番目の文書を表示する必要がありました。

このような動的クエリがどのように反応しているかを知ることができますか?その自然な反応性を維持していますか?

答えて

1

あなたのリアクションバーを正しく取得して設定していないようです。あなただけのmyReactiveVar.get()を呼び出すことはできません - あなたのコードがあるべきよう、彼らは(通常は)テンプレートのインスタンスに接続されている:あなたはconst instance = Template.instance();でインスタンスにアクセスして、あなたの$where機能であなたがinstance.currentMonth.get()を使用することになり、

pendingMTsヘルパーではとイベントでinstance.currentYear.get()

、イベントの第2引数は、テンプレートのインスタンスであるので、あなたが持っているでしょう:

'change #monthForecast' (event, templateInstance) { 
    event.preventDefault(); 
    const target = event.target; 
    templateInstance.currMonth.set(target.value); 
}, 

だからあなたはあまりにも遠くはありません!

https://docs.meteor.com/api/reactive-var.html

https://themeteorchef.com/tutorials/reactive-dict-reactive-vars-and-session-variables

+0

Rubie、あなたの答えに感謝をたくさん。私はちょうどどこの:演算子のReactive varsの使用をテンプレートヘルパー内で行うことで問題を解決することができましたvar timeRef = diff(moment([currYear.get()、currMonth.get()]) )そして、$の中の変数を使用します。このようにして、Reactive varsのいずれかが変更されるとヘルパーが再評価されます。 – francis

+0

Rubyを指しているリンクでは、「ReactiveVarsはグローバル名を持たず、代わりにローカルで作成され使用されるかもしれません。データ、具体的にはテンプレートレベルで "、しかし、私はそれがローカルテンプレートインスタンスに添付することが必須であると言う場所を見つけることができませんでした。私の解決策では、少なくとも必ずしも必要ではないことが確認されていますが、あなたが提案したように(もし私がチェックする)ローカルにアタッチされたときに一般的にうまく機能するならば、 – francis

+0

私は100%フォローしていますが、反応的でグローバルに利用できるものを保存したい場合は、Sessionを使用できます。私はそれをスキミングしただけですが、このスレッドは興味深いと思います:http://stackoverflow.com/questions/31580261/meteor-using-sessions-and-reactivevarそれは役に立ちますか? – rubie

関連する問題