2013-08-27 59 views
0

我正在努力解决一个问题,我将解释给出一个简单的演示。即使没有数据变化,模板也会重新渲染

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后(我知道,因为我安慰.log)。当我查询People集合为name模板提供数据时,我使用transform选项,因此nicks字段中的更改不应该对name模板产生影响。

流星文档支持此:

光标是一个反应性数据源。第一次在反应计算(例如模板或自动运行)中检索具有提取,映射或forEach的游标文档时,Meteor将注册对基础数据的依赖关系。对光标中的文档进行更改的集合的任何更改都会触发重新计算。

为什么模板name被重新渲染呢?

回答

0

该模板因为您更改了People集合而被重新渲染。

当您更改People集合时,Meteor会自动假定它提供的所有数据都需要重新计算。 (你的哪个name模板通过Template.name.fname一样。

即使你变换光标在输出时,People收集以某种方式发生了变化。在使用之前转换查询完成,换句话说,它不是变换

流星认为,也许你的文档{'fname':'John'}可能有其他可能已经改变的字段,它需要重新检查它(nicks字段已被改变)。转换然后在查询后应用。

您的HTML可能不会交流在这一点上,只有当游标返回不同的东西时,才会改变html。

如果在任何情况下(即表单被清除或DOM被更改),您可以使用{{#isolate}} {{/isolate}}块来确保只有它们内部的所有内容都被重新渲染,并且没有任何内容。