2014-12-15 2 views
0

Я пытаюсь вставить рекламные блоки в шаблон списка 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. Я не могу разобраться, как вставлять рекламные объявления программно с произвольными интервалами. Это бесконечный прокрутки и вам нужно будет добавить объявление несколько раз.

ответ

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 для обнаружения новых данных и инъекции соответственно.

+0

Вы запустили это в дикой природе?Я бы ожидал, что шаблон «dataList» будет отображаться до того, как будут обработаны все документы в каждом цикле ('# listContainer'). Это приводит к мерцанию? – user728291

+0

Я не упоминал, что это было на бесконечном свитке. Это решение не будет вставлять объявление несколько раз – Chris

+0

Мне нравится этот метод лучший, однако я до сих пор не могу его постоянно отображать. Он кратко показывает adsTemplate, а затем, когда данные загружены, вы больше не можете их видеть – Chris

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> 
+0

Будет ли это работать с бесконечным решением прокрутки? – Chris

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 будет иметь объявление, вставленное в третью позицию.

+2

Вы должны, вероятно, упомянуть о недостатках этого решения (без мелкозернистых обновлений). –

Смежные вопросы