问题
i want a loading template to appear before the site has all data to be rendered.
And after the serverside Method gives me the Data(from an API [async]) via Meteor.call i want to load the correct layout.
I tried many ways found on Google which describe similar but not exatcly the same problem. Including the way to define a function with ready handle, also doesn´t work. I can´t get it running.
i don´t want to use Collections because this is user specific Data.( i think this is not efficient to make a collection for each user [no logged in users], or do i miss something) Is this possible?
Here my Code. The console logs 2 befor 1.
Router.route('/search/:term',{
name: 'search',
loadingTemplate: 'loading',
waitOn : function(){
var term = this.params.term;
//i think here has be something differnet either with return subscribe or function with ready-handle
Meteor.call('search',term,function(err, response) {
Session.set('shops', response);
console.log(1);
});
},
action : function(){
console.log(2);
this.render();
}
});
Template.search.helpers(
{
"shops" : function(){
return Session.get('shops');
}
}
);
Server Side Method returns an Array.
Thanks for help
回答1:
Iron Router's waitOn
will not wait on a Meteor.call()
. Instead, the way to set this up is to subscribe
to the record set in waitOn
, publish
a function which contains the Meteor.call()
, and then create a client-side collection for each user to receive the results of the call. It will look something like the following:
Client:
// create this collection only on the client
// to receive publication on a per-user basis
Search = new Mongo.Collection('search');
Route:
Router.route('/search/:term',{
waitOn : function(){
var term = this.params.term;
return Meteor.subscribe('search', term);
}
});
Server:
Meteor.publish('search', function(term){
check(term, String);
var self = this;
Meteor.call('search', term, function(error, result){
if (result){
self.added("search", "mySearch", {results: result});
self.ready();
} else {
self.ready();
}
});
});
Meteor.methods({
search: function(term){
//do the api call and return it
}
});
I recommend taking a look at the example of the low-level added/changed/removed publish function in the Meteor documentation here. It is a dense section but ultimately contains what you need to get your use case working.
回答2:
I know you've accepted the answer about getting this done via creating a psuedo-publication, but I think there's a more fitting solution.
The good folks at ars-nebula already did the work to make a Meteor method call wait
-able using the https://github.com/arsnebula/reactive-promise/ library.
Get the promise via:
var $dep = new $.Deferred();
Meteor.call("myMethod", function(err, result) {
if (err) { $dep.reject(err); }
$dep.resolve(result);
});
var promise = $dep.promise();
Then wait on it via
Router.route('/route', {
"loadingTemplate": loading,
"waitOn": function() {
return ReactivePromise.when("myTask", $def1.promise(), $def2.promise());
},
"action": function() {
this.render("myTemplate");
}
});
As a shortcut, the Meteor.promise library (https://atmospherejs.com/deanius/promise) can get you a Promise for a method call with merely
Meteor.promise("methodName", args);
Pubsub is flexible, but reactivity goes beyond that - give this a try and let me know!
来源:https://stackoverflow.com/questions/29923423/meteor-iron-router-waiton-without-subscribe