Como usar os methods do Meteor dentro de um ajudante de modelo

Como posso definir um método Meteor que também pode ser chamado em um auxiliar de modelo?

Eu tenho esses dois arquivos:

arquivo: lib / test.js

Meteor.methods({ viewTest : function (str) { return str; } }); 

arquivo: client / myView.js

 Template.helloWorld.helpers({ txt : function () { var str = Meteor.call('viewTest', 'Hello World.'); return str; } }); 

Quando eu dou “str” ​​uma string normal, tudo funciona bem. Mas neste caso, meu modelo não recebe nenhum valor. Eu defini – para o teste – no mesmo arquivo onde o método é uma function normal e tentei chamar a function. O erro que recebi foi que a function não existe. Então eu acho que o Meteor tenta renderizar o template antes que ele saiba alguma coisa sobre os methods que eu defini para ele. Mas eu acho que isso é um pouco incomum – não é?

Existe agora uma nova maneira de fazer isso (Meteor 0.9.3.1) que não polui o namespace 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); }); } 

No retorno de chamada ‘criado’, você cria uma nova instância de uma ReactiveVariable (consulte os documentos ) e anexa-a à instância do modelo.

Em seguida, você chama seu método e, quando o retorno de chamada é triggersdo, você anexa o valor retornado à variável reativa.

Você pode configurar seu auxiliar para retornar o valor da variável reativa (que é anexada à instância do modelo agora) e será executada novamente quando o método retornar.

Mas note que você terá que adicionar o pacote reactive-var para que ele funcione

 $ meteor add reactive-var 

Sashko adicionou um pequeno pacote chamado metodo-reativo-metodo para resolver este problema.

 $ meteor add simple:reactive-method 
 Template.helloWorld.helpers({ txt: function() { return ReactiveMethod.call('viewTest', 'Hello World.'); } }); 

Como eu indico em erros comuns , os ajudantes devem ser livres de efeitos colaterais, então eu usaria essa técnica com caucanvas. No entanto, é um atalho realmente útil para casos em que:

  • O ajudante deve triggersr apenas uma vez (não depende do estado reativo).
  • O método invocado não altera o database.

Você precisa relacionar seu valor de retorno com uma variável de session, pois a solicitação é assíncrona:

 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); }); } 

Então .rendered deve ser chamado uma vez quando o seu template carregar (pelo menos deveria com a nova versão do Meteor).

O valor seria chamado e exibido. Caso contrário, diria “Carregando”.

Os methods no lado do cliente são asynchronouss e seu valor de retorno é sempre indefinido. Para obter o valor real retornado pelo método, você precisa fornecer um retorno de chamada:

 Meteor.call('method', 'argument', function(error, result) { .... }); 

Agora, não há maneira fácil de usar o resultado em seu ajudante. No entanto, você pode armazená-lo em seu modelo como um object de dados e, em seguida, retorná-lo ao assistente:

 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; }; 

Esse é o comportamento esperado. Você não está usando methods como eles são destinados.

Seu código define um método de servidor viewTest e um stub de método correspondente no cliente com o mesmo nome.

Meteor.call('viewTest', 'Hello World.'); chama remotamente o viewTest no servidor e, em paralelo, executa o stub no cliente.

Em relação ao valor de retorno do stub, consulte a documentação aqui , em particular:

No cliente, o valor de retorno de um stub é ignorado. Os stubs são executados por seus efeitos colaterais: eles são destinados a simular o resultado do que o método do servidor fará, mas sem esperar pelo atraso de ida e volta.

Em relação ao valor de retorno do método do servidor, consulte a documentação aqui , em particular:

No cliente, se você não passar um retorno de chamada e não estiver dentro de um stub, a chamada retornará indefinida e você não terá como obter o valor de retorno do método. Isso ocorre porque o cliente não tem fibras, portanto, não há realmente nenhuma maneira de bloquear a execução remota de um método.

Existe um pequeno pacote para isso por @msavin:
https://atmospherejs.com/msavin/fetcher