即使没有数据更改,也会重新呈现模板

时间:2013-08-27 16:14:28

标签: meteor

我正在努力解决一个问题,我会解释一下这个问题。

People集合中有以下非常简单的文档。

{  
    "_id" : "vxmLRndHgNocZouJg",  
    "fname" : "John" ,  
    "nicks" : [ "Johnny" , "Jo"]  
}

现在让我们考虑以下模板。基本上我会显示用户名和带有输入字段的昵称列表,用于添加更多昵称。

<head>
  <title>test</title>
</head>
<body>
  {{> name}}<br/>
  {{> nicks}}
</body>

<template name="name">
    <input type="text" value="{{fname}}"/>
</template>

<template name="nicks">
    {{#each nicks}}
        <div>{{this}}</div>
    {{else}}
        no nicks yet
    {{/each}}
    <input type="text" name="nicks"/>
    <input type="submit"/>
</template>

我的客户端javascript代码如下:

Template.name.fname = function() {
    return People.findOne({"fname" : "John"},{
        transform : function(doc) {
            return doc.fname;
        }
    });
}

Template.name.rendered = function() {
  console.log('Template "name" rendered!');
}

Template.nicks.nicks = function() {
  var john = People.findOne({"fname" : "John"});
  if(john) return john.nicks;
}
Template.nicks.events({
'click input[type="submit"]' : function () {
  var johnId = People.findOne({"fname" : "John"})._id; // demo code
  People.update(johnId,{
      $addToSet : {
          nicks : $('input[name="nicks"]').val()
      }
  })
}
});

我的问题是,在添加昵称(文档中nicks字段的更新)之后,模板name被重新呈现(我知道因为我在console.log中)。当我查询People集合以提供name模板的数据时,我使用transform选项,因此nicks字段中的更改不应对name模板产生影响。< / p>

Meteor docs支持这一点:

  

游标是一个反应数据源。第一次在反应计算(例如,模板或自动运行)中使用fetch,map或forEach检索游标文档时,Meteor将注册对基础数据的依赖。对更改游标中文档的集合进行的任何更改都将触发重新计算。

为什么重新呈现模板name呢?

1 个答案:

答案 0 :(得分:0)

重新呈现模板是因为您更改了People集合。

当您更改People集合时,Meteor会自动假定需要重新计算其提供数据的所有内容。 (您的name模板通过Template.name.fname执行。

即使您转换了光标的输出,People集合也以某种方式发生了变化。查询在使用变换之前完成,换句话说,它不是查看的变换而是整个集合。

Meteor认为,使用{'fname':'John'}的文档可能包含其他可能已更改的字段,需要重新查询以进行检查(nicks字段已被更改)。然后在重新查询之后应用转换。

此时您的HTML可能实际上没有变化,只有当光标返回不同的内容时才会更改html。

如果它在任何场景中都成了问题(即表单被清除或者DOM不应该被更改),你可以使用{{#isolate}} {{/isolate}}块来确保只有它们内部的所有内容都被重新呈现而且没有任何内容外部。