2013-08-27 58 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}}塊來確保只有它們內部的所有內容都被重新渲染,並且沒有任何內容。