为什么这个模板没有反应?

时间:2015-10-08 02:50:41

标签: meteor meteor-blaze meteor-helper

为什么这不是被动的?更重要的是它如何被反应?

我想将数据保存在Mongo中并在模板中使用。我可以使用ReactiveVar或ReactiveDict。我需要两份数据吗?

Suspects.findOne('bruce')是否已经返回被动对象?我尝试将human答案直接放在布鲁斯身上,但没有触发更新。

事件触发,log(this)显示bruce的答案已更改,但模板未重新渲染。这样做的好方法是什么?

http://meteorpad.com/pad/KoH5Qu7Fg3osMQ79e/Classification

Meteor 1.2加上iron:router

<head>
  <title>test</title>
</head>

<template name="question">
  {{#unless isAnswered 'human'}}   <!--  :-<  I'm not reacting here -->
    <div>Sir, are you classified as human?</div>
    <button id="no">No, I am a meat popsicle</button>
    <button id="smokeYou">Smoke you</button>
  {{else}}
    <div> Classified as human?  <b>{{answers.human}}</b></div>
  {{/unless}}
</template>

JavaScript:

// Why isn't this reactive?
if (Meteor.isClient) {
  Template.question.helpers({
    isAnswered: function (question) {     // :-<  I'm not reactive
      var suspect = Template.instance().data;
      return (typeof suspect.answers[question] !== 'undefined');
    }
  });

  Template.question.events({
    'click #no': function () {
      this.answers.human = "No"; // :-<  I'm not reactive
      console.log(this);
    },
    'click #smokeYou': function() {
      this.answers.human = "Ouch";    // :-<  I'm not reactive
      console.log(this);
    }
  });
}

// Collection
Suspects = new Meteor.Collection('suspects');
if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
    Suspects.upsert('bruce', { quest: 'for some elements', answers: {}});
  });
  Meteor.publish('suspects', function() {
    return Suspects.find({});
  });
}

// Iron Router
Router.route('/', {
  template: 'question',
  waitOn: function() {
    return Meteor.subscribe('suspects');
  },
  data: function() {
    return Suspects.findOne('bruce');
  }
});

谢谢: - )

2 个答案:

答案 0 :(得分:1)

非常接近你只需要使用ReactiveVar的声音,它几乎可以解释它是什么:) http://docs.meteor.com/#/full/reactivevar

以及如何使用它

if (Meteor.isClient) {
  Template.question.onCreated(function () {
    this.human = new ReactiveVar();
  });

  Template.question.helpers({
    isAnswered: function (question) {
      return Template.instance().human.get();
    }
  });

  Template.question.events({
    'click #no': function (e, t) {
      t.human.set('No');
      console.log(t.human.get());
    },
    'click #smokeYou': function(e, t) {
      t.human.set('Ouch');
      console.log(t.human.get());
    }
  });
}

更新:如果您使用的是游标,我通常希望将其保留在模板级别而不是铁路由器上:

if (Meteor.isClient) {
  Template.question.helpers({
    isAnswered: function (question) {
      return Suspects.findOne('bruce');
    }
  });

  Template.question.events({
    'click #no': function (e, t) {
      Suspects.update({_id: ''}, {$set: {human: 'No'}});
    },
    'click #smokeYou': function(e, t) {
      Suspects.update({_id: ''}, {$set: {human: 'Ouch'}});
    }
  });
}

答案 1 :(得分:1)

events实际上并未更新被动数据源(db记录)。而不是做:

Template.question.events({
  'click #no': function () {
    this.answers.human = "No";
  }
});

事件需要通过直接updateMeteor.call()Meteor.method执行数据库操作。例如:

'click #no': function(){
  Suspects.update('bruce', {'answers': {'human': 'no'}});
}

如果您使用此模式,则还需要设置正确的allowdeny规则以允许从客户端代码进行更新。 http://docs.meteor.com/#/full/allow。方法通常最终成为更大项目的更好模式。

此外,我不确定Template.instance().data helper中的Template.currentData()是否会被动反应。我会使用{{1}}来确定。 http://docs.meteor.com/#/full/template_currentdata