2016-08-30 72 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