关于最佳实践的流星新手查询

时间:2015-08-13 08:28:13

标签: javascript meteor

学习流星,这很棒,但我在"最佳实践"中苦苦挣扎。

例如,我正在构建一个小示例测验,如下所示:

Question : 1 + 1 = ?    ---> Dropdown box [1, 2, 3]
Question : 1 + 0 = ?    ---> Dropdown box [1, 2, 3]
Question : 1 - 1 = ?    ---> Dropdown box [1, 2, 3]
Question : 2 + 1 = ?    ---> Dropdown box [1, 2, 3]

然后,在底部是一个按钮,上面写着"给我打分"。

当按下该按钮时,它应该通过每个问题然后放一点"正确"或"错误"在下拉框旁边。

所有这些看起来像:

<template name="questions">
    <div class="jumbotron">
        {{#each questions}}
            <span class="lead">{{question}} </span>
            <select class="answerDropDown">     
              {{#each answer}}              
                <option value={{this}}>{{this}}</option>
              {{/each}}                 
            </select>

            <span id="correctornot">{{correctornot}}</span>
        {{/each}}       
    </div>
</template>

我使用以下方式从数据库中提取数据:

Questions = new Mongo.Collection("questions");

一切都很好。我已插入事件并且反应良好等等......等等。

我不能轻易做到的是如何使校正器不起作用。嗯......我这么说,但我的意思是没有任何意义。

我想象的是当我得到数据时:

Template.questions.helpers({
questions: function() {
  return Questions.find({});
}

我想为每个问题添加额外的数据,但这并不意味着要保存在数据库中。

我想我只是在寻找正确的方法来解决它。即使答案也没有保存在任何地方,所以当我检查它是否正确时,我目前正在查看下拉选择事件中更改的会话变量。

无论如何,欢迎所有的建议。

干杯。

1 个答案:

答案 0 :(得分:3)

您想要的是Blaze的反应性,而不会在您的数据库中保留信息。答案? 反应性客户端值!它们有不同的形式:

在指定的上下文(例如helpersTracker.autorun)中进行评估时,每当反应变量中的值发生变化时,所述上下文中包含的代码将再次运行,因此,在助手,触发模板中的更改。

示例:使用Session

在这里,我们将看到使用内置Session对象实现此目的的更简单方法。我们假设您的questions模板包含在名为form的模板中,该模板包含您的提交按钮:

<template name="form">
  {{> questions}}
  <form id="form">
    <input type="submit" value="Score me" />
  </form>
</template>

首先,我们必须在submitted模板呈现时将false会话变量设置为form

Template.form.onRendered(function () {
  Session.set('submitted', false);
});

然后,抓住表单提交事件,而不是提交,我们将新的submitted反应变量设置为true。

Template.form.events({
  'submit #form': function (e, t) {
    e.preventDefault();
    // do some prior validation here if needed
    Session.set('submitted', true);
  }
});

现在,我们需要做的就是检查submitted模板助手是否submitted设置为truefalse。如果是true,我们将继续显示correctornot帮助程序的结果,该结果将获取下拉列表中选定的值,并将其与存储在当前数据上下文中的问题的正确答案进行比较( each循环)。假设此答案存储在您问题的correctAnswer属性中:

Template.questions.helpers({
  'questions': function() {
    return Questions.find({});
  },
  'submitted': function () {
    return Session.get('submitted');
  },
  'correctornot': function () {
      var userResponse = $('#'+this._id+'.answerDropDown').val();
      return (this.correctAnswer == userResponse);
  }
});

这是我们略微增强的questions模板:

<template name="questions">
    <div class="jumbotron">
        {{#each questions}}
            <span class="lead">{{question}} </span>
            <select id="{{_id}}" class="answerDropDown">     
              {{#each answer}}              
                <option value={{this}}>{{this}}</option>
              {{/each}}                 
            </select>
            {{#if submitted}}
              <span id="correctornot">{{correctornot}}</span>
            {{/if}}
        {{/each}}       
    </div>
</template>

正如您所看到的,只需很少的代码,您就可以获得良好的反应行为。

如果我不想用无意义的旗帜污染Session该怎么办?

然后,您可以查看reactive variables。一旦掌握了逻辑,它们就很容易实现。你的案例中有点棘手的部分是你似乎使用嵌套模板:触发反应性变化的提交按钮和对它做出反应的问题列表不在同一个模板中。因此,您需要在模板实例之间导航才能访问submitted反应变量。请查看this answer有关此主题的线索。