Как использовать методы Meteor внутри помощника шаблона
Как определить метод Метеор, который также можно вызвать в помощнике шаблона?
У меня есть два файла:
file: lib/test.js
Meteor.methods({
viewTest : function (str) {
return str;
}
});
file: client/myView.js
Template.helloWorld.helpers({
txt : function () {
var str = Meteor.call('viewTest', 'Hello World.');
return str;
}
});
Когда я даю "str" нормальную строку, все работает нормально. Но в этом случае мой шаблон не получает никакой ценности. Я определил - для теста - в том же файле, где метод является нормальной функцией и попытался вызвать функцию. Ошибка, которую я получил, заключалась в том, что функция не существует. Поэтому я думаю, что Метеор пытается отобразить шаблон, прежде чем он узнает о методах, которые я определил для него. Но я думаю, что это немного необычно - не так ли?
Ответы
Ответ 1
Теперь есть новый способ сделать это (Meteor 0.9.3.1), который не загрязняет пространство имен Session
Template.helloWorld.helpers({
txt: function () {
return Template.instance().myAsyncValue.get();
}
});
Template.helloWorld.created = function (){
var self = this;
self.myAsyncValue = new ReactiveVar("Waiting for response from server...");
Meteor.call('getAsyncValue', function (err, asyncValue) {
if (err)
console.log(err);
else
self.myAsyncValue.set(asyncValue);
});
}
В обратном вызове "created" вы создаете новый экземпляр ReactiveVariable (см. docs) и присоединяете его к экземпляру шаблона.
Затем вы вызываете свой метод и когда срабатывает обратный вызов, вы присоединяете возвращаемое значение к реактивной переменной.
Затем вы можете настроить своего помощника, чтобы вернуть значение реактивной переменной (которая теперь привязана к экземпляру шаблона), и она будет повторно запускаться при возврате метода.
Но обратите внимание, что вам придется добавить пакет reactive-var для работы
$ meteor add reactive-var
Ответ 2
Сашко добавил аккуратный маленький пакет под названием meteor-reactive-method, чтобы решить эту проблему.
$ meteor add simple:reactive-method
Template.helloWorld.helpers({
txt: function() {
return ReactiveMethod.call('viewTest', 'Hello World.');
}
});
Как я отмечаю в распространенных ошибках, помощники должны быть свободными от побочных эффектов, поэтому я буду использовать этот метод с осторожностью. Тем не менее, это действительно удобный ярлык для случаев, когда:
- Помощник должен срабатывать только один раз (он не зависит от реактивного состояния).
- Выбранный метод не мутирует базу данных.
Ответ 3
Вам нужно связать свое возвращаемое значение с переменной Session, поскольку запрос является асинхронным:
Template.helloWorld.helpers({
txt : function () {
return Session.get("txt") || "Loading";
}
});
Template.helloWorld.created = function() {
Meteor.call('viewTest', 'Hello World.', function(err, result) {
Session.set("txt", result);
});
}
Так что .rendered следует вызывать один раз, когда ваш шаблон загружается (по крайней мере, он должен быть с более новой версией Meteor.)
Значение будет вызываться и отображаться. В противном случае он сказал бы "Загрузка".
Ответ 4
Способы на стороне клиента асинхронны, и их возвращаемое значение всегда undefined. Чтобы получить фактическое значение, возвращаемое методом, вам необходимо предоставить обратный вызов:
Meteor.call('method', 'argument', function(error, result) {
....
});
Теперь нет простого способа использовать результат в вашем помощнике. Однако вы можете сохранить его в своем шаблоне в качестве объекта данных, а затем вернуть его в помощнике:
Template.template.created = function() {
var self = this;
self.data.elephantDep = new Deps.Dependency();
self.data.elephant = '';
Meteor.call('getElephant', 'greenOne', function(error, result) {
self.data.elephant = result;
self.data.elephantDep.changed();
});
};
Template.template.showElephant = function() {
this.elephantDep.depend();
return this.elephant;
};
Ответ 5
Это ожидаемое поведение. Вы не используете methods
, поскольку они предназначены.
Ваш код определяет метод сервера viewTest
и соответствующий дескриптор метода на клиенте с тем же именем.
Meteor.call('viewTest', 'Hello World.');
удаленно вызывает viewTest
на сервере и параллельно запускает заглушку на клиенте.
Что касается возвращаемого значения заглушки, см. документацию здесь, в частности:
На клиенте обратное значение заглушки игнорируется. Запуски запускаются для их побочных эффектов: они предназначены для имитации результата что будет делать серверный метод, но не дожидаясь раунда задержки отключения.
Что касается возвращаемого значения метода сервера, см. документацию здесь, в частности:
На клиенте, если вы не проходите обратный вызов, и вы не находитесь внутри заглушка, вызов вернет undefined, и у вас не будет способа получить возвращаемое значение метода. Это потому, что у клиента нет волокон, поэтому на самом деле он не может блокироваться на пульте дистанционного управления выполнение метода.
Ответ 6
Для этого есть небольшой небольшой пакет @msavin:
https://atmospherejs.com/msavin/fetcher