Meteor JS - 避免过度使用助手的设计模式

时间:2016-08-30 14:26:42

标签: javascript meteor

我有以下帮手,我觉得有点过度劳累。这基本上做的是循环我拥有的一堆SVG,如果它们在DB中有相应的数据,那么SVG的填充颜色应该改变(数据的可视化表示)。

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

我还在学习如何使用Meteor。之前,我已经使用仍然安装的autopublish实现了这个,因此它被附加到Template.rendered。但在我转向使用pubs / subs之后,我发现我无法像以前那样以相同的方式实现它,因为:

  1. 无法从.rendered
  2. 返回帮助程序
  3. 无论如何,在呈现模板时,订阅数据尚未准备就绪。所以没有显示数据。
  4. 这是我以前的实施:

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

    所以现在我已将功能附加到帮助程序,但感觉非常错误和臃肿。是否有更好的方法可以在不使用助手的情况下获得相同的结果?

1 个答案:

答案 0 :(得分:0)

我知道其中一些是在我的评论中,但是当我想到它时,我决定给出一个更全面的答案。

如果您不关心有反应数据,请使用Meteor methods

如果您需要反应式数据,我建议您使用Flow Router来帮助解决订阅未准备好的问题,方法是这样检查:

FlowRouter.subsReady("treatments");

您也可以将ReactiveVars与自动运行一起使用。 Here's在reactiveVars上开了个好头。我知道这是一个很多阅读,但它肯定会有所帮助。

所以在渲染中你可以做类似的事情:

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这个主题的一个很好的资源。

此外,如果您使用的是Meteor的最新版本,则{I}已被弃用renderedonRendered docs