在Meteor中重用或重新创建反应源是否更好?

时间:2014-01-16 10:34:35

标签: node.js meteor handlebars.js

我有一个名为'contacts'的模板。里面是一个#each,它使模板“联系”。用户可以按下“编辑”按钮,该按钮使用编辑行的mongo id设置会话变量。然后该行被动地重新呈现为“编辑”模式。

Template.contact.viewEditing = function() {
    return Session.get("contactViewEditingId") === this._id;
}

html使用viewEditing助手几次,例如:

{{#if viewEditing}}
<div class="panel-heading">EDITING!</div>
{{/if}}

我需要在.rendered()中绑定一些javascript。如果我们正在编辑,我想再次检查。我可以想到两个选项:

  1. 我应该在template.rendered()中调用Template.content.viewEditing()吗?这会节省反应性计算吗?
  2. 或者我应该在if语句中复制pasta。这个选项似乎违反了DRY。
  3. 选项1:

    Template.contact.rendered = function() {
        if( Template.contact.viewEditing.call(this.data) ) {
            // Bind some fancy jQuery
            bindEditInPlace(this.data);
        }
    }
    

    选项2:

    Template.contact.rendered = function() {
        if( Session.get("contactViewEditingId") === this._id ) {
            // Bind some fancy jQuery
            bindEditInPlace(this.data);
        }
    }
    

    我认为在您的模板中多次放置{{viewEditing}}并不会“花费”任何额外费用。从逻辑上讲,我认为在其他地方使用这个助手更好。也许我需要更多帮助来理解反应性计算。谢谢!

2 个答案:

答案 0 :(得分:1)

Helpers在Deps.Computation中运行,这意味着每次在帮助器中引用和修改反应变量时,它都会重新运行。

Template.rendered是每次重新呈现模板时运行的回调(通常在模板中的帮助程序被重新运行时发生),但它本身不是反应计算。

因此,使用模板助手或在渲染回调中复制粘贴代码无关紧要:两种方式都不会触发反应计算失效,因为我们不在其中。

就DRY而言,您可以像这样重构代码:

function isContactViewEditing(contactView){
    return Session.equals("contactViewEditingId",contactView._id);
}

Template.contact.helpers({
    viewEditing:isContactViewEditing
});

Template.contact.rendered=function(){
    if(isContactViewEditing(this.data)){
        //
    }
};

答案 1 :(得分:1)

我认为saimeunt的答案是正确的,特别是如果你在函数中有更复杂的逻辑,你不想复制。

创建一个可以在helper和.rendered回调中重用的本地函数。

如果你有一个案例,你想要使用反应源减去反应性,你可以通过将它包装在Deps.nonreactive函数中使其无反应,如下所示:

Deps.nonreactive(function(){
   //Reactive stuff here
});

关于反应性问题,请注意他从使用Session.get到Session.equals的更改。 Session.get将导致其用于在会话变量的每次更改时重新计算的任何反应计算。因此,如果您在具有不同ID的多个位置使用此帮助程序,并且您更改了会话变量,则每个会话变量将重新计算并重新呈现它们所使用的模板。仅当相等更改时,Session.equals仅使计算无效。因此,当您使用Session.equals时,将会话变量从一个不相等的id更改为另一个不相等的id将不会导致计算/模板重新运行。

对于帮助程序仅返回Session.equals结果的特定示例,您可以考虑创建一个全局句柄助手,可以使用任何会话变量和任何值为您执行此操作。如下所示。

Handlebars.registerHelper('sessionEquals', function (key, value) {
    return Session.equals(key, value);
});

然后在模板中使用它:

{{#if sessionEquals 'contactViewEditingId' _id}}
    <div class="panel-heading">EDITING!</div>
{{/if}}

在呈现可编辑项目时的模板中,添加唯一的类名称以将项目标记为可编辑。然后在绑定javascript时的Template.rendered回调中使用一个选择器来查找该类,并且仅绑定到具有该特殊类的元素。