我正在尝试在Meteor列表模板中插入广告块。代码将比我描述的更容易显示:
// dataList.js
Template.dataList.helpers({
dataList : function() {
return DataList.find();
});
// dataList.html
<template name="dataList">
{{#each dataList}}
<div class="col-xs-3">
{{name}} (and other data)
</div>
{{/each}}
</template>
我想要的结果是这样的
<div class="col-xs-3">
Jon Snow
</div>
<div class="col-xs-3"> <----This inserted programmatically
<div id="ad">
Buy a Destrier - 5 Golden Stags
</div>
</div>
<div class="col-xs-3">
Tyrion Lannister
</div>
<div class="col-xs-3">
The Hound
</div>
效果类似于Foodgawker.com上的广告效果。我无法确定如何以随机方式以编程方式插入广告。 这是一个无限滚动,需要多次添加广告。
答案 0 :(得分:0)
// 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
我认为仍有待解决的问题,例如: - 如何使这与排序一起工作?
以下是想法如何实现您想要的结果。
方法是客户端等待呈现列表(仅发生一次),然后在您选择的位置注入广告。
假设:
代码:
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+')')
)
}
如果你想要注入很多广告,因为列表应该是无限的,那么最好使用Tracker.autorun来检测新数据并进行相应的注入。
答案 1 :(得分:0)
您可以从列表中随机选择一个_id,然后只在模板中显示该文档后面的广告。
像这样:
//.js
Template.dataList.created = function(){
var ids = DataList.find().map( function( doc ){ return doc._id });
this.showAdId = Random.choice( ids ); //need to add 'random' package of meteor core
};
Template.dataList.helpers({
dataList: function(){
return DataList.find({},{transform: function( doc ){
doc.showAd = doc._id === Template.instance().showAdId;
return doc;
});
}
});
//.html
<template name="dataList">
{{#each dataList}}
<div class="col-xs-3">
{{name}} (and other data)
</div>
{{#if showAd}} <!-- check new field to see whether this is the doc with an ad -->
<div class="col-xs-3">
<div id="ad">
Buy a Destrier - 5 Golden Stags
</div>
</div>
{{/if}}
{{/each}}
</template>
答案 2 :(得分:0)
以前的答案太复杂了;只需更新您的助手:
dataList : function() {
var d = _.map( DataList.find().fetch(), function(v) { return {value: v}; });
return _.union( d.slice(0,2), {
type: 'ad',
value: 'Buy a Destrier - 5 Golden Stags'
} ,d.slice(2));
});
因此,dataList会将广告插入第三位。