Meteor.js: как вызвать вспомогательный метод из события?
Я подозреваю, что не делаю этого способом Метеор. Я делаю общий интерактивный календарь.
У меня есть шаблон календаря:
<template name="calendar">
<h2>Calendar</h2>
<div class="calendar">{{#each days}}
{{> day}}
{{/each}}
</div>
</template>
С помощником, который возвращает объект дня:
{
date: thisDate.getDate(),
dateString: dateString,
done: done,
today: isToday
}
У меня есть шаблон дня:
<template name="day">
<div class="day {{stateString}}">{{date}}</div>
</template>
С некоторыми помощниками (meetingID
теперь жестко запрограммирован для разработки):
Template.day.helpers({
state: function(){
// retreive from DB
var s = Meetings.findOne({"_id":meetingID}).dates[this.dateString];
return s;
}
stateString: function(){
var stateString;
switch(this.state){
case -1: stateString = "unknown"; break;
case 0: stateString = "unavailable"; break;
case 1: stateString = "available"; break;
}
if(this.done) stateString = "done";
return stateString;
}
});
state() получает состояние из db, а stateString() выбирает правильное имя класса для этого состояния.
Когда вы нажимаете на него, вы циклически переключаете состояния (1: доступно, 0: недоступно, -1: неизвестно):
Template.day.events({
"click": function(){
if(this.done) return false; // no state changes for past days!
console.log(e);
var newState = this.state + 1;
if(newState > 1) newState = -1;
var q = "dates."+this.dateString+"."+Meteor.userId()+".state";
console.log(q+ " / "+this.state+" / "+newState);
Meetings.update(meetingID, {$set:{q:newState}});
return false;
}
})
У меня есть как минимум две проблемы:
1) Как мне вызвать помощника state() из события click?
2) Мое обновление db не работает - оно создает документ "q" вместо использования строки, хранящейся в q.
Я уверен, что это не дает основополагающего понимания правильного пути для этого - пожалуйста, помогите!
Ответы
Ответ 1
Просто расширяем ответ на @mark. Вероятно, вы хотите сохранить state
в качестве реактивной переменной, чтобы хелпер stateString
обновлялся при изменении состояния. Если я правильно понимаю, вы на самом деле не пытаетесь использовать помощник state
в своем шаблоне - это просто необходимо для помощника строки и события. Сначала добавьте пакет reactive-var
:
meteor add reactive-var
Я бы рекомендовал сделать что-то вроде этого для вашего шаблона:
Template.day.created = function() {
this.state = new ReactiveVar();
this.autorun(_.bind(function() {
var meetingDates = Meetings.findOne(meetingID).dates[this.data.dateString];
var currentState = meetingDates[Meteor.userId()].state;
this.state.set(currentState);
}, this);
};
Template.day.helpers({
stateString: function() {
if (this.done) {
return 'done';
}
switch(Template.instance().state.get()) {
case -1: return 'unknown';
case 0: return 'unavailable';
case 1: return 'available';
}
}
});
Template.day.events({
'click': function(event, template) {
if (this.done) {
return;
}
var newState = template.state.get() + 1;
if (newState > 1) {
newState = -1;
}
var modifier = {$set: {}}
modifier.$set['dates.'+this.dateString+'.'+Meteor.userId()+'.state'] = newState;
Meetings.update(meetingID, modifier);
}
});
Ответ 2
Сверху моей головы один способ сохранить данные между помощниками и событиями в одном шаблоне - сохранить его как свойство внутри экземпляра шаблона. Так, например, у вас может быть что-то похожее на это:
Template.day.created = function () {
// here `this` refers to template instance
this.state = -1;
};
Template.day.helpers({
state: function () {
var s = Meetings.findOne({"_id":meetingID}).dates[this.dateString];
Template.instance().state = s;
return s;
},
...
});
Template.day.events({
'click': function () {
...
var state = Template.instance().state;
...
}
});
Что касается проблемы с q
, вам нужно сначала создать объект, иначе q
будет интерпретироваться как фактическое имя поля, а не переменная (обратите внимание, как не существует различия между "q" и q внутри запрос).
var query = {};
query[q] = newState;
Meetings.update(meetingID, { $set: query });
Надеюсь, это поможет!
Ответ 3
Доступ к помощникам шаблонов доступа из любого места:
Template.<name>.__helpers.get('<helper>').call()