2013-07-30 57 views
0

爲什麼模板會呈現與我的模板中的每個模板相關的次數。Template #each&rendering

<template name="carousel"> 
<div class="pikachoose"> 
<ul class="carousel" > 
{{#each article}} 
    <li><a href="#"><img src="{{image}}" width="500" height="250" alt="picture"/></a><span>{{caption}}</span></li> 
{{/each}} 
    </ul> 
    </div> 

</template> 

Template.carousel.article = function() { 
return News.find({},{limit: 3}); 

} 

Template.carousel.rendered = function() { 
//$(".pika-stage").remove(); 
alert($(".carousel").html()); 
//$(".carousel").PikaChoose({animationFinished: updateNewsPreview}); 
} 

在這種情況下,它會提醒3次。

回答

0

該問題可能與使用.rendered回調有關。每次循環運行時,DOM都會更新,以便回調再次運行。

當我在過去遇到這個問題時,我發現儘可能使用Meteor事件處理程序很有幫助,以消除像這樣的加載順序問題。在這種情況下,也許你可以嘗試超時,這樣.remove().PikaChoose()調用只能在DOM在一段時間內保持安靜之後才運行。希望這對你有用。

+1

' 。'rendered'不是問題的原因,而是一個指標。這個問題是反應性的副作用。此外,使用超時等待數據被提取是一個**糟糕的主意。 –

+0

你說得很好,先生。 –

1

這就是Meteor處理數據更新的方式。您的article數據函數返回將在模板中使用的遊標。最初,遊標是空的,並且一次從服務器中提取一篇文章。每次提取文章時,光標的內容都會更改(現在它還有一篇文章),因此反應式方法會導致模板重新渲染。

 


 

如果你需要確保你的代碼只運行一次,還有根據你所需要的幾種可能性。

最簡單的就是用created代替rendered

如果修改DOM元素,你還可以標記元素修改,這樣你就不會處理他們兩次:

Template.carousel.rendered = function() { 
    _.each(this.findAll('.class'), function(element){ 
     if($(element).data('modified')) return; 
     $(element).data('modified', true); 
     ... 
    }); 
}; 

您可以將光標禁用的反應,雖然這是一個可悲的解決方案:

Articles.find(..., {reactive: false}); 

中最激進的,也是最通用的是觀察,當數據被完全加載:

Deps.autorun(function() { 
    Meteor.subscribe('articles', { 
     ready: function() { 
      ... 
     }, 
    }); 
});