一次显示集合中的一个文档的模板事件?

template event to display one document from a collection at a time?

鉴于此:

if (Meteor.isServer) {
  Meteor.startup(function () {
    if (Players.find().count() === 0) {
      var names = ["Ada Lovelace", "Grace Hopper", "Marie Curie",
                   "Carl Friedrich Gauss", "Nikola Tesla", "Claude Shannon"];
      _.each(names, function (name) {
        Players.insert({
          name: name,
          score: Math.floor(Random.fraction() * 10) * 5
        });
      });
    }
  });
}

我如何编写一个模板事件来一次显示一个名字,单击按钮将遍历列表的其余部分?

如果我理解你的问题你可以写

@yourTemplate

<template name="yourTemplate">
  {{#each players}}
     {{name}} - {{score}}
  {{/each}}
  <button class="add-player">Add Player</button>
</template>

@yourJSFile

//We set default value at Session variable numberOfPlayers
Template.yourTemplate.created = function () {
  Session.setDefault("numberOfPlayers",1);
}

//We set a helper which return players at template
Template.yourTemplate.helpers({
  players: function () {
    return Players.find({}, {limit:Session.get("numberOfPlayers")});
  }
});

//When you click at button just add one at Session variable and that triggers the helper to return the next player
Template.yourTemplate.events({
   "click .add-player": function (event, template) {
      event.preventDefault();
      var numOfPlayers = Session.get("numberOfPlayers");
      Sessionl.set("numberOfPlayers", numOfPlayers+1);
    }
});

请注意,今晚不是您正在寻找的答案,但不幸的是,meteor 还不支持 mongoDB 的 cursor.hasNext()cursor.next() 功能。否则你可以在模板事件代码中做类似的事情:

  var players;

  Template.leaderboard.created = function(){
    players = null;
  }

  Template.leaderboard.events({
    'click .next': function () {
      if(players.hasNext()){
        players.next();
      }
    }
  }

它支持 cursor.forEach() 方法。你想详细实现什么?我确信您的用例有可行的解决方案,请告诉我们更多详细信息。

如果您迭代的集合不会改变,或者您不需要处理这些数据变化,您可以这样做:

工作示例 http://meteorpad.com/pad/89r8ZKR8M5fHLCyx5/IterateStaticData

// store some local state here for your iteration
var currentIndex = 0;
var myPlayers;
Template.leaderboard.events({
  'click #iterateNames' : function(){
    currentIndex++;
      // only load the data once
    if(!myPlayers){
      myPlayers = Players.find({}).fetch();
    }
    if(currentIndex===myPlayers.length){
      currentIndex = 0;
    }
    var currentPlayer = myPlayers[currentIndex];
    Session.set("nextPlayer",currentPlayer);
  }
});

如果您正在迭代的集合确实发生了变化,并且您需要处理这些数据变化,您可以这样做:

工作示例 http://meteorpad.com/pad/3aEjv5HaGPzSDcvKY/IterateDynamicData

var found = [];  // people we've found in this iteration loop

function findNext(){
  var queryNext = {_id:{$nin:found}};
  return Players.findOne(queryNext);
}

Template.leaderboard.events({
  'click #iterateNames' : function(){

    var nextPlayer = findNext();
    if(nextPlayer){
      found.push(nextPlayer._id);
    }
    if(!nextPlayer){
      found = [];
      nextPlayer = findNext();
      found.push(nextPlayer._id);
    }

    // do something with the next item
    someDomElement.innerHTML = nextPlayer.name;

})

虽然 meteorpad 示例应用程序似乎在迭代时始终显示顺序,但我认为不能保证该顺序。如果有人能详细说明,那将很有趣。