Meteor: iron-router => waitOn without subscribe

后端 未结 2 1906
春和景丽
春和景丽 2020-12-18 14:28

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.ca

相关标签:
2条回答
  • 2020-12-18 15:13

    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!

    0 讨论(0)
  • 2020-12-18 15:17

    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.

    0 讨论(0)
提交回复
热议问题