新思路
// client side collection, not synchronized with server side...
DataListWithAds= new Mongo.Collection(null);
Template.DataList.destroyed= function(){
this.observer.stop();
}
Template.DataList.created= function(){
// DataList is collection anywhere
// get handler of observer to remove it later...
this.observer = DataList.find().observe({
// observe if any new document is added
// READ : http://docs.meteor.com/#/full/observe
addedAt:function(document, atIndex, before){
console.log(atIndex, document, self);
// immediately insert original document to DataListWithAds collection
DataListWithAds.insert(document);
// if some condition is true, then add ad.
if(atIndex % 5 == 1){
DataListWithAds.insert({
name:"AD", score:document.score, isAd:true
});
}
}
})
}
// use local collection to display items together with ads
Template.dataList.helpers({
dataList : function() {
return DataListWithAds.find();
});
})
模板也应该稍微调整一下:
<template name="dataList">
{{#each dataList}}
{{#if isAd}}
ADVERTISEMENT
{{else}}
<div class="col-xs-3">
{{name}} (and other data)
</div>
{{/if}}
{{/each}}
</template>
可在此处找到概念证明:
http://meteorpad.com/pad/SoJe9dgp644HKQ7TE/Leaderboard
我认为仍有一些问题需要解决,例如:
- 如何使它与排序一起工作?
老想法
以下是一个想法,您可以如何实现您想要的结果。
方法是客户端等到您的列表呈现(仅发生一次),然后在您选择的位置注入一个广告。
假设:
- 您的广告在模板 adsTemplate 中定义
- 项目在 div 中:#listContainer
代码:
Template.dataList.rendered = function(){
// position after which ads should be added
// you can generate random number
var adsPosition = 10;
// inject HTML from template **Template.adsTemplate**
// with data **adsData**
// to HTML element #listContainer
// after HTML element at position adsPosition
Blaze.renderWithData(
Template.adsTemplate,
adsData,
this.find('#listContainer'),
this.find('#listContainer .col-xs-3:nth-child('+adsPosition+')')
)
}
如果要注入很多广告,因为 list 应该是无限的,那么最好使用Tracker.autorun 检测新数据并相应地注入。