2016-08-30 75 views
2

我有以下的幫手,我認爲是有點過度勞累。這基本上是通過一系列SVG進行循環,如果它們在數據庫中有相應的數據,那麼SVG的填充顏色應該會改變(數據的可視化表示)。流星JS - 設計模式,以避免過度幫助者

Template.patientContentTreatment.helpers({ 

    treatments: function() { 

     var completedTeeth = $('.svg-tooth-completed > .tooth'); // get all the svgs 

     var currentNumber, currentPart; 

     for (var i = 0; i < completedTeeth.length; i++) { 
      // get a related data-id 
      currentNumber = $(completedTeeth[i]).closest('.svg-tooth-completed').data('id'); 

      // get the related data-title 
      currentPart = $(completedTeeth[i]).data('title'); 

      if (Treatments.find({ patient_id: Session.get('currentPatient'), tooth_number: currentNumber, tooth_part: currentPart }).fetch().length) { 
       // loop through each SVG and change the fill color if correspoding data is founf 
       $(completedTeeth[i]).css({'fill': '#54a6f8', 'fillOpacity': .8}); 
      } 
     } 

     return Treatments.find({patient_id: Session.get('currentPatient')}); 
    } 
}); 

我還在學習如何使用流星。之前,我已經實現了這個自動發佈仍然安裝,所以它被附加到Template.rendered。但之後,我搬到了使用酒吧/潛艇,我發現我不能完全實現它以同樣的方式,因爲我是因爲收到:

  1. 沒有辦法返回從.rendered
  2. 的一個幫手無論如何,當模板呈現時,訂閱數據還沒有準備好。所以沒有數據顯示。

這裏是我以前的實現:

Template.single_patient_treatment_plan.rendered = function() { 
     /* 
     loop through all teeth 
     find if any of them have any findings or treatments attached to them in the database 
     if so, change the fill color 
     */ 

    var completedTeeth = $('.svg-tooth-completed > .tooth'), 
     currentNumber, currentPart; 

    Tracker.autorun(function() { 

     for (var j = 0; j < completedTeeth.length; j++) { 
      currentNumber = $(completedTeeth[j]).closest('.svg-tooth-completed').data("id"); 
      currentPart = $(completedTeeth[j]).data("title"); 

      if (Treatments.find({patient_id: Session.get("current_patient"), tooth_number: currentNumber, tooth_part: currentPart}).fetch().length) { 
       $(completedTeeth[j]).css({"fill": "#54A6F8", fillOpacity: .8}); 
      } 
     } 
    }); 

所以,現在我已經附加功能,以輔助,但感覺非常錯誤和臃腫。有沒有更好的方法來實現相同的結果,而不使用幫手?

+0

您可能想看看FlowRouter來處理訂閱尚未準備好的問題。 https://github.com/kadirahq/flow-router#subscription-management。 如果你不需要你的數據是被動的https://guide.meteor.com/methods.html,你也可以嘗試使用Meteor服務器方法。 – Jeremiah

+0

SVG如何渲染?如果它是在另一個Meteor模板中完成的,那麼大部分邏輯應該轉到模板助手那裏,而不是試圖修改已經從其他地方渲染過的東西。 – Waiski

+0

你能否顯示你的模板(html)代碼?我懷疑你可以在牙齒級別實現一個助手,這將節省大量的數據庫查找,同時避免在整個陣列上發生反應性重新計算。 –

回答

0

我知道其中的一些是在我的評論中,但是當我想到更多一點時,我決定給出一個更全面的答案。

如果您不在乎有無效數據,請使用Meteor methods

如果你想反應的數據我會建議使用Flow Router協助處理的不是通過檢查它像這樣準備您預訂的問題:

FlowRouter.subsReady("treatments"); 

您也可以使用ReactiveVars與自動運行。 Here's反應變量的一個很好的開始。我知道這是很多的閱讀,但它肯定會有所幫助。

所以,你的渲染,你可能只是這樣做:

this.treatment = new ReactiveVar({}); 

this.autorun(function() { 
    if(FlowRouter.subsReady("treatments")) { 
     // other computations or functions 
     this.treatment.set(Treatments.find...); 
    } 
}); 

這將使您的treatment變量反應,讓你在任何地方訪問treatment在此模板的實例,並簡化您的幫助:

treatments: function() { 
    return Template.instance().get(); // Reactive computation (see note) 
} 

注意:助手是被動計算。意思是如果你將一個反應變量放入一個幫助器中,它就會成爲一種自動運行的類型。 Here's在這個問題上的一個很好的資源。另外,如果您使用的是流星的最新版本,則rendered已被棄用,而不再支持onRenderedonRendered docs