2015-04-28 3 views
2

Я хочу, чтобы шаблон загрузки отображался до того, как на сайте будут отображаться все данные.Meteor: iron-router => waitOn без подписки

И после того, как метод serveride дал мне данные (из API [async]) через Meteor.call, я хочу загрузить правильный макет.

Я пробовал много способов найти в Google, которые описывают похожие, но не очень похожие проблемы. Включая способ определения функции с готовым дескриптором, также не работает. Я не могу заставить его работать.

Я не хочу использовать Коллекции, потому что это данные, специфичные для пользователя. (Я думаю, что это неэффективно, чтобы сделать сбор для каждого пользователя [без входа в систему], или я что-то пропустил) Возможно ли это?

Здесь мой код. Консольные журналы 2 для 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'); 
     } 
    } 
); 

Метод боковой стороны сервера возвращает массив.

Спасибо за помощь

+0

Прямо сейчас, поскольку вы не возвращаете дескриптор с готовой функцией из 'waitOn',' action' будет выполняться немедленно. У вас все еще есть код, возвращающий функцию с готовым дескриптором, который вы пробовали? – Curtis

+0

Нет. Когда я сделал это и проверил, было ли this.ready() в методе действий, это всегда было правдой, и оно запускалось/повторялось бесконечно. – delueg

ответ

4

Iron маршрутизатора с waitOn не будет ждать на Meteor.call(). Вместо этого способ установить это - subscribe в запись, установленную в waitOn, publish, функцию, которая содержит Meteor.call(), а затем создать клиентскую сторону для каждого пользователя, чтобы получить результаты вызова. Это будет выглядеть примерно так:

Клиент:

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

Я рекомендую взглянуть на пример низкого -level добавлена ​​/ изменена/удалена функция публикации в Meteor documentation here. Это плотный раздел, но в конечном итоге содержит то, что вам нужно, чтобы работать с вашим прецедентом.

+0

Работает как шарм. Просто добавлено заявление о возврате перед тем, как Meteor.subscribe («поиск», срок); в противном случае я получил n исключение, и загрузчик не запускается. Большое спасибо – delueg

+0

Отлично. Я добавил возвращение для будущих читателей. –

+0

@JeremyS. Привет! Благодарим вас за публикацию этого решения. Это очень полезно! Следуя вашему решению, я хотел бы включить 'show.modal()' в мой 'Meteor.call()'. Мы ценим любые предложения. [link] (https://stackoverflow.com/questions/46306445/how-do-i-modal-show-from-the-server-inside?noredirect1_comment79575051_46306445) – SirBT

3

Я знаю, что вы приняли ответ о том, как это сделать, создав публикацию psuedo, но я думаю, что есть более подходящее решение.

Хорошие люди в ars-туманности уже сделали работу, чтобы сделать метод Meteor wait -able, используя библиотеку https://github.com/arsnebula/reactive-promise/.

Получить обещание через:

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) вы можете получить обещание для вызова метода с только

Meteor.promise("methodName", args); 

Pubsub является гибким, но реактивность выходит за рамки этого - дайте это попытка и дайте мне знать!

Смежные вопросы