Meteor: iron-router => waitOn 没有订阅

Meteor: iron-router => waitOn without subscribe

我希望在网站呈现所有数据之前出现一个加载模板。

在服务器端方法通过 Meteor.call 给我数据(来自 API [async])之后,我想加载正确的布局。

我尝试了很多在 Google 上找到的方法,它们描述了相似但不完全相同的问题。包括用就绪句柄定义函数的方法,也不起作用。我听不懂 运行。

我不想使用集合,因为这是用户特定的数据。(我认为为每个用户[未登录用户]创建集合效率不高,或者我是否遗漏了什么)这可能吗?

这是我的代码。控制台在 1 之前记录 2。

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

服务器端方法returns一个数组。

感谢帮助

Iron Router 的 waitOn 不会等待 Meteor.call()。相反,设置它的方法是subscribewaitOn中的记录集,publish一个包含Meteor.call()的函数,然后创建一个client-side集合为每个用户接收调用的结果。它将类似于以下内容:

客户:

// create this collection only on the client
// to receive publication on a per-user basis

Search = new Mongo.Collection('search');

路线:

Router.route('/search/:term',{
  waitOn : function(){
    var term = this.params.term;
    return Meteor.subscribe('search', term);
  }
});

服务器:

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

我建议看一下 Meteor documentation here 中低级 added/changed/removed 发布功能的示例。这是一个密集的部分,但最终包含使您的用例正常工作所需的内容。

我知道您已经接受了通过创建伪出版物来完成这项工作的答案,但我认为还有一个更合适的解决方案。

ars-nebula 的优秀人员已经完成了使用 https://github.com/arsnebula/reactive-promise/ 库进行 Meteor 方法调用 wait 的工作。

通过以下方式获得承诺:

var $dep = new $.Deferred();
Meteor.call("myMethod", function(err, result) {
  if (err) { $dep.reject(err); }
  $dep.resolve(result);
});

var promise = $dep.promise();

然后通过

等待
Router.route('/route', {
  "loadingTemplate": loading,
  "waitOn": function() {
    return ReactivePromise.when("myTask", $def1.promise(), $def2.promise());
  },
  "action": function() {
    this.render("myTemplate");
  }
});

作为一种快捷方式,Meteor.promise 库 (https://atmospherejs.com/deanius/promise) 可以让您通过

获得方法调用的 Promise
Meteor.promise("methodName", args);

Pubsub 很灵活,但反应性不止于此 - 试一试并告诉我!