有没有办法在Meteor模板之间插入?

时间:2014-12-15 12:22:53

标签: javascript templates meteor

我正在尝试在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上的广告效果。我无法确定如何以随机方式以编程方式插入广告。 这是一个无限滚动,需要多次添加广告。

3 个答案:

答案 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

我认为仍有待解决的问题,例如: - 如何使这与排序一起工作?

旧想法

以下是想法如何实现您想要的结果。

方法是客户端等待呈现列表(仅发生一次),然后在您选择的位置注入广告

假设:

  • 您的广告在模板 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+')')
  )
}

如果你想要注入很多广告,因为列表应该是无限的,那么最好使用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会将广告插入第三位。