2017-04-21 135 views
1

這是關於包含動態查詢的助手的問題,涉及反應變量和$ where操作符,當反應變量值更改時不會重新運行。然後關於如何解決它會導致一個奇怪的系統行爲和崩潰。非反應助手和模板#每次崩潰

我在這,我們要顯示的#each循環中發現插入文檔的列表中選擇模板:

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

在任務收集的文件的pendingMTs助手搜索與動態並以某種方式精心製作尤其是圓形,涉及使用其中運算符$ simplified-查詢:

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

參與搜索的兩種反應瓦爾在創建模板的定義

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:

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

的第一個問題是,幫助不重新運行,儘管我們通過修改事件處理程序反應變量的值:爲什麼?

思考,這可能對事實反應瓦爾在哪裏的功能,我爲了添加一個簡單的線條在助手的開始僅僅是爲了創建輔助意識,爲他們的$裏面是由於:

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

現在肯定會讓助手在任何時候重新運行任何2個反應變量。但不幸的是這導致了一個很奇怪的現象:

  • 如果無功增值經銷商進行了修改,但並沒有影響由輔助檢索到的文件,系統精細運行,但:
  • 當修飾的反應瓦爾造成輔助檢索一個多個文檔超過文檔數檢索到的第一次,系統崩潰(因此新文件未在#each模板所示):

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

在查找原因時,我發現給出的錯誤索引號3在這種情況下總是等於第一次執行幫助程序時檢索到的文檔數。在這種情況下,修改其中一個無功變量的值後,系統崩潰時必須顯示第4個文檔。 我發現https://github.com/GroundMeteor/db/issues/184一些可能相關的問題

誰能指出如何涉及$其中具有反應瓦爾動態查詢可以做,保持其自然的反應?

回答

1

看起來你沒有得到正確的反應變量。你不能只是調用myReactiveVar.get() - 他們(通常)連接到模板實例,以便您的代碼應該是:

pendingMTs幫手,你const instance = Template.instance();訪問實例,然後在你的$where功能你可以使用instance.currentMonth.get()instance.currentYear.get()

在活動現場,事件的第二個參數是模板實例,所以你會:

'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

若碧,非常感謝您的回答。我可以通過在$ where:操作符中使用Reactive vars來解決這個問題,方法是在模板助手var timeRef = diff(moment([currYear.get(),currMonth.get()]) ),然後使用$ where中的變量:.通過這種方式,只要有任何反應性變化發生變化,就會重新評估助手。 – francis

+0

在您指出Rubie的鏈接中,據說「ReactiveVars沒有全局名稱,而是可以在本地創建和使用它們,例如附加到模板實例」,還說「ReactiveVar更適合本地數據,特別是在模板級別「,但是我找不到一個地方說它強制將它們附加到本地模板實例。我的解決方案證實它至少不是必需的,但是如果按照您的建議在本地連接時它們的工作通常會更好(我將檢查它),那麼最好在文檔中指出它。 – francis

+0

不知道我是否100%關注,但如果您想存儲全局可用且可用的內容,則可以使用Session。我只是剔除它,但我認爲這個線程可能是有趣的:http://stackoverflow.com/questions/31580261/meteor-using-sessions-and-reactivevar。這有幫助嗎? – rubie