javascript - template - Cómo usar los métodos de Meteor dentro de un helper de plantilla
meteor template events (6)
¿Cómo puedo definir un método Meteor que también se puede llamar en una plantilla auxiliar?
Tengo estos dos archivos:
archivo: lib / test.js
Meteor.methods({
viewTest : function (str) {
return str;
}
});
archivo: client / myView.js
Template.helloWorld.helpers({
txt : function () {
var str = Meteor.call(''viewTest'', ''Hello World.'');
return str;
}
});
Cuando le doy a "str" una cuerda normal todo funciona bien. Pero en este caso, mi plantilla no tiene ningún valor. Definí - para la prueba - en el mismo archivo donde el método es una función normal e intenté llamar a la función. El error que obtuve fue que la función no existe. Así que creo que Meteor intenta renderizar la plantilla antes de que sepa algo sobre los métodos que definí para ella. Pero creo que esto es un poco inusual, ¿no?
Ahora hay una nueva forma de hacerlo (Meteor 0.9.3.1) que no contamina el espacio de nombres de la sesión.
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);
});
}
En la devolución de llamada ''creada'', usted crea una nueva instancia de una Variable Reactiva (ver docs ) y la adjunta a la instancia de la plantilla.
A continuación, llama a su método y cuando se activa la devolución de llamada, adjunta el valor devuelto a la variable reactiva.
Luego puede configurar su ayudante para devolver el valor de la variable reactiva (que ahora está adjuntada a la instancia de la plantilla), y se volverá a ejecutar cuando regrese el método.
Pero tenga en cuenta que deberá agregar el paquete reactivo-var para que funcione
$ meteor add reactive-var
Este es el comportamiento esperado. No estás usando los methods
como están destinados.
Su código define un método de servidor viewTest
y un trozo de método correspondiente en el cliente con el mismo nombre.
Meteor.call(''viewTest'', ''Hello World.'');
Llama remotamente a viewTest
en el servidor y en paralelo ejecuta el stub en el cliente.
En cuanto al valor de retorno del talón, consulte la documentación here , en particular:
En el cliente, el valor de retorno de un stub se ignora. Los stubs se ejecutan por sus efectos secundarios: están destinados a simular el resultado de lo que hará el método del servidor, pero sin esperar el retraso de ida y vuelta.
En cuanto al valor de retorno del método del servidor, consulte la documentación here , en particular:
En el cliente, si no pasa una devolución de llamada y no está dentro de un talón, la llamada devolverá indefinida, y no tendrá forma de obtener el valor de retorno del método. Esto se debe a que el cliente no tiene fibras, por lo que en realidad no hay forma de bloquear la ejecución remota de un método.
Hay un pequeño paquete fino para esto por @msavin:
https://atmospherejs.com/msavin/fetcher
Los métodos en el lado del cliente son asincrónicos, y su valor de retorno siempre está indefinido. Para obtener el valor real devuelto por el método, debe proporcionar una devolución de llamada:
Meteor.call(''method'', ''argument'', function(error, result) {
....
});
Ahora, no hay una manera fácil de usar el resultado en su ayudante. Sin embargo, puede almacenarlo en su plantilla como un objeto de datos y luego devolverlo en el asistente:
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;
};
Necesita interconectar su valor de retorno con una variable de sesión ya que la solicitud es asincrónica:
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);
});
}
Por lo tanto, debe invocarse .rendered una vez cuando se carga su plantilla (al menos debería hacerlo con la versión más nueva de Meteor).
El valor se llamaría y se mostraría. De lo contrario, diría "Cargando".
Sashko agregó un pequeño paquete ordenado llamado meteor-reactive-method para resolver este problema.
$ meteor add simple:reactive-method
Template.helloWorld.helpers({
txt: function() {
return ReactiveMethod.call(''viewTest'', ''Hello World.'');
}
});
Como señalo en los errores comunes , los ayudantes deberían estar libres de efectos secundarios, así que usaría esta técnica con precaución. Sin embargo, es un atajo realmente útil para casos donde:
- El ayudante debe disparar solo una vez (no depende del estado reactivo).
- El método invocado no muta la base de datos.