【问题标题】:Render template from session object从会话对象渲染模板
【发布时间】:2015-11-25 14:06:24
【问题描述】:

我对 Meteor 和一般编程很陌生,所以如果这是一个荒谬的问题,我很抱歉。

目前我的程序很小,所以我将发布整个内容,因为我认为的问题可能不是真正的问题。

该应用程序用于在 MMA 事件之前挑选战斗(谁将获胜,哪一回合等)。我的问题是您应该能够从下拉列表中选择一个事件(该事件被设置为 Session 对象),那么我的 pickArea 模板应该从 session 对象中获取当前选择的事件,然后为每次战斗呈现选项 top pick 。

我知道 Session 对象已正确设置和更新,但似乎将它连接到我的 pickArea 助手时出现问题,因为我没有收到第二条 console.log 消息。我认为这就是为什么我的选项都没有呈现的原因。

我从控制台收到两个错误,但不知道如何使用它们来帮助我:

Exception from Tracker recompute function:
TypeError: Cannot read property '0' of null

这是我的代码:

Javascript

//add Collections
  Results = new Mongo.Collection('results');
  Events = new Mongo.Collection('events');
  Picks = new Mongo.Collection('picks');

  if (Meteor.isClient) {

  Tracker.autorun(function () {
    console.log('The selectedEvent ID is: ' +
      Session.get('selectedEvents')
    );
  });  

  var user = "John"; //Just for testing purposes, will be replaced with actual user

  //get list of events to pick from (from Events Collection)
  //save selection in Session object
  Template.main.helpers({
    events: function () {
      return Events.find({}, {
        fields: {
          event: 1,
          _id: 1
        }
      });
    },
    isSelected: function () {
      return Session.equals('selectedEvents', this._id) ? 'selected' : '';
    }
  });
  //if they change the selection update the Session object
  Template.main.events = {
    'change #eventSelection': function (evt) {
      Session.set('selectedEvents', evt.currentTarget.value);
    }
  };

  //connect template to selected event  
  Template.pickArea.helpers({
    event: function () {
      return Events.findOne({
        _id: Session.get('selectedEvents')
      });
      console.log("This worked.. recieved " + Session.get('selectedEvents') )
    }
  });

  Template.pickArea.events({
    'click #save-button': function (event, template) {
      $('#fights').each(function() {

      var currentFight = fights.fightNumber; //might be wrong  
      var selectedEvent = Session.get('selectedEvents'); //dropdown selection (again not sure if done correctly)
      var fighterChoice = $('input[name="winner"]:checked').val()
      var finishChoice = $('input[name="finish"]:checked').val();
      var rdChoice = $('input[name="rd"]:checked').val();

      Picks.insert({
        user_ID:user, 
        event:selectedEvent, 
        fightNumber:currentFight, 
        fighter:fighterChoice, 
        finish:finishChoice, 
        round:rdChoice
        });

      });
    }
  });


  }

  if (Meteor.isServer) {
    Meteor.startup(function () {
      // code to run on server at startup

      //Empty the database and fill it with Test data
      Events.remove({});
      Picks.remove({});

      Events.insert({
        event: 'UFC 193',
        fights:[
          {
          fightNumber:1,
          fighter1: 'Stefan Struve',
          fighter2: 'Jared Rosholt',
          rounds: 3
        },
        {
          fightNumber:2,
          fighter1: 'Uriah Hall',
          fighter2: 'Robert Whittaker',
          rounds: 3
        },
        {
          fightNumber:3,
          fighter1: 'Mark Hunt',
          fighter2: 'Antonio Silva',
          rounds: 3
        },
        {
          fightNumber:4,
          fighter1: 'Joanna Jedrzejczyk',
          fighter2: 'Valerie Letourneau',
          rounds: 5
        },
        {
          fightNumber:5,
          fighter1: 'Ronda Rousey',
          fighter2: 'Holly Holm',
          rounds: 5
        }
        ]  
      });

      Events.insert({
        event: 'UFC 194',
        fights:[
          {
          fightNumber:1,
          fighter1: 'Max Holloway',
          fighter2: 'Jeremy Stephens',
          rounds: 3
        },
        {
          fightNumber:2,
          fighter1: 'Demian Maia',
          fighter2: 'Gunnar Nelson',
          rounds: 3
        },
        {
          fightNumber:3,
          fighter1: 'Ronaldo Souza',
          fighter2: 'Yoel Romero',
          rounds: 3
        },
        {
          fightNumber:4,
          fighter1: 'Chris Weidman',
          fighter2: 'Luke Rockhold',
          rounds: 5
        },
        {
          fightNumber:5,
          fighter1: 'Jose Aldo',
          fighter2: 'Conor Mcgregor',
          rounds: 5
        }
        ]  
      });

    });
  }

HTML

<head>
    <title>fight_picks</title>
  </head>

  <body>
    <h1>Welcome to Meteor!</h1>
    {{> main}}
  </body>

  <template name="main">
      <p> Choose an event </p>
      <select name="event-select" id="eventSelection">
        {{#each events}}
        <option value="{{_id}}" {{isSelected}} >{{event}}</option>
        {{/each}}
      </select>  
    <div class="main-container">
      <h1>UFC Fight Picks Game! </h1>
      {{> pickArea}}  
    </div>
  </template>

  <template name="pickArea">
    <div class="each-fight">
      {{#with event}}
      <ul id='fights'>
      {{#each fights}}
        <li>{{> fightData}}</li>
      {{/each}}
      </ul>
      {{/with}}
      <br>
      <button id='save-button' > Save </button>  
    </div>
  </template>

  <template name='fightData' >
    <div class="slections">
      <p> Who do you think will win fight {{fightNumber}} ?
        <br>
      <input type="radio" name="winner" value="{{fighter1}}" checked/>
      {{fighter1}}
      <input type="radio" name="winner" value="{{fighter2}}" />
      {{fighter2}}
      </p>
        <br>
      <p> Finish Type?
        <br>
      <input type="radio" name="finish" value="DEC" /> 
      Decision
      <input type="radio" name="finish" value="KO/TKO" />
      KO/TKO
      <input type="radio" name="finish" value="SUB" />
      Submission
      <input type="radio" name="finish" value="Null" checked/>
      No Guess
      </p>
        <br>
      <p> Round?
        <br>
      {{#if fights.round 5}} <!-- if the # of rounds is 5 (may need gt?)-->
        <input type="radio" name="rd" value="1" />
        Round 1 
        <input type="radio" name="rd" value="2" />
        Round 2 
        <input type="radio" name="rd" value="3" />
        Round 3
        <input type="radio" name="rd" value="4" />
        Round 4 
        <input type="radio" name="rd" value="5" />
        Round 5
        <input type="radio" name="rd" value="Null" checked/>
        No Guess
      {{else}}
        <input type="radio" name="rd" value="1" />
        Round 1 
        <input type="radio" name="rd" value="2" />
        Round 2 
        <input type="radio" name="rd" value="3" />
        Round 3
        <input type="radio" name="rd" value="Null" checked/>
        No Guess
      {{/if}}
      </p>
    </div>  
  </template>

感谢您的帮助,很抱歉发布所有这些代码,但希望确保任何想要帮助的人都有足够的信息。另外(不是任何人都愿意),但如果有人想重用此代码的任何工作部分,如果他们正在做类似的事情,他们是欢迎的。

【问题讨论】:

  • 所以我尝试对pickArea的辅助事件进行硬编码:返回UFC 193事件,但它仍然没有渲染。所以我猜这个问题出在我的模板中

标签: javascript meteor spacebars


【解决方案1】:

这很尴尬,但我最终意识到问题出在我的 if 块助手中

 {{#if fights.round 5}} <!-- This is not a real thing :( -->
    <input type="radio" name="rd" value="1" />
    Round 1 
    <input type="radio" name="rd" value="2" />
    Round 2 
    <input type="radio" name="rd" value="3" />
    Round 3
    <input type="radio" name="rd" value="4" />
    Round 4 
    <input type="radio" name="rd" value="5" />
    Round 5
    <input type="radio" name="rd" value="Null" checked/>
    No Guess
  {{else}}
    <input type="radio" name="rd" value="1" />
    Round 1 
    <input type="radio" name="rd" value="2" />
    Round 2 
    <input type="radio" name="rd" value="3" />
    Round 3
    <input type="radio" name="rd" value="Null" checked/>
    No Guess
  {{/if}}

显然我的语法是错误的,我知道我对它不是 100% 有信心,但我认为如果它是错误的,它仍然会渲染 else 部分,但它只是没有渲染任何那个模板。所以我删除了 if else 标签,只用了 5 轮来看看它是否有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多