为什么这个模板不是反应式的?
Why isn't this template reactive?
为什么这不是反应式的?更重要的是,如何让它具有反应性?
我希望将数据保存在 Mongo 中并在模板中使用。我可以使用 ReactiveVar 或 ReactiveDict。我需要两份数据吗?
Suspects.findOne('bruce')
return 不是反应对象吗?我尝试将 human
答案直接放在 Bruce 上,但没有触发更新。
事件触发,log(this) 显示布鲁斯的答案已更改,但模板没有重新呈现。这样做的好方法是什么?
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');
}
});
谢谢 :-)
非常接近,你只需要根据它的声音使用 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'}});
}
});
}
events
实际上并没有更新反应数据源(数据库记录)。而不是做:
Template.question.events({
'click #no': function () {
this.answers.human = "No";
}
});
事件需要执行数据库操作,可以通过直接 update
或通过 Meteor.call()
到 Meteor.method
。例如:
'click #no': function(){
Suspects.update('bruce', {'answers': {'human': 'no'}});
}
如果您使用此模式,您还需要设置正确的 allow
和 deny
规则以允许从客户端代码进行更新。 http://docs.meteor.com/#/full/allow。方法通常最终成为更大项目的更好模式。
此外,我不确定您的 helper
中的 Template.instance().data
是否会反应。我会使用 Template.currentData()
代替只是为了确定。 http://docs.meteor.com/#/full/template_currentdata
为什么这不是反应式的?更重要的是,如何让它具有反应性?
我希望将数据保存在 Mongo 中并在模板中使用。我可以使用 ReactiveVar 或 ReactiveDict。我需要两份数据吗?
Suspects.findOne('bruce')
return 不是反应对象吗?我尝试将 human
答案直接放在 Bruce 上,但没有触发更新。
事件触发,log(this) 显示布鲁斯的答案已更改,但模板没有重新呈现。这样做的好方法是什么?
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');
}
});
谢谢 :-)
非常接近,你只需要根据它的声音使用 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'}});
}
});
}
events
实际上并没有更新反应数据源(数据库记录)。而不是做:
Template.question.events({
'click #no': function () {
this.answers.human = "No";
}
});
事件需要执行数据库操作,可以通过直接 update
或通过 Meteor.call()
到 Meteor.method
。例如:
'click #no': function(){
Suspects.update('bruce', {'answers': {'human': 'no'}});
}
如果您使用此模式,您还需要设置正确的 allow
和 deny
规则以允许从客户端代码进行更新。 http://docs.meteor.com/#/full/allow。方法通常最终成为更大项目的更好模式。
此外,我不确定您的 helper
中的 Template.instance().data
是否会反应。我会使用 Template.currentData()
代替只是为了确定。 http://docs.meteor.com/#/full/template_currentdata