Принудете iron-router да върне готовност от waitOn

В момента изглежда не е възможно да се принуди състояние на ready() в маршрута. Например: Имам чакане на 2 абонамента. Един от тях връща Meteor.Error - сега маршрутът ще бъде в състояние на зареждане без край. Има ли препоръчителен начин да кажете на iron-router "waitOn докато абонаментът е готов ИЛИ абонаментът е неуспешен с грешка"?

Редактиране:

За да обясня моя специален случай: waitOn е за маршрут, който е за търсене. Аргументите за търсене са "какво" и "къде". В „къде“ имам планов низов адрес и трябва да го преобразувам в географска координата. За това използвам конвертора на googlemaps от страна на сървъра (заради неговата синхронизация). Когато не беше намерен адрес, трябва да върна грешка като „Този ​​адрес трябва да е грешен“. За това имам нужда от функционалността да върна грешка.

Когато го направя, както каза Дейвид Уелдън, трябва да направя тази стъпка в метода waitOn, но конверторът на googlemaps от страна на клиента не е Sync - вместо това е async, така че това няма да работи.


person TJR    schedule 25.10.2014    source източник


Отговори (1)


Общи препоръки

Добре е вашите издатели да извеждат грешки, но тези условия трябва да бъдат изпълнени само ако клиентът направи грешното нещо. С други думи, вие решавате грешен проблем - трябва да се абонирате само когато знаете, че издателят няма да изведе грешка. Да разгледаме един пример:

Да предположим, че вашият маршрут трябва да се абонира за newPosts и postsForSuperuser. Да предположим, че издателят postsForSuperuser ще изведе грешка, ако потребителят не е суперпотребител. Сега е работа на клиента да не позволи това да се случи. Дефиницията waiton може да изглежда така:

waitOn: function() {
  var subs = [Meteor.subscribe('newPosts')];

  if (Roles.userIsInRole(Meteor.user(), ['superuser']))
    subs.push(Meteor.subscribe('postsForSuperuser'));

  return subs;
}

Тъй като условно добавяме абонамента postsForSuperuser, не даваме възможност на издателя да изведе грешка.

Вашият конкретен случай на употреба

Вашият случай е малко по-сложен, защото механично клиентът прави правилното нещо, но въвеждането от потребителя може да се окаже лошо. В този случай не мисля, че хвърлянето на грешка е подходящо. Ето някои препоръки:

  1. Избягвайте проблема, като проверите адреса чрез извикване на метод, преди да промените маршрута.

  2. Ако се установи, че даден адрес е невалиден, незабавно пуснете функцията за публикуване return this.ready(). Това ще предотврати неуспеха на вашия маршрут, но ще останете да предполагате, че причината да нямате данни е поради адреса. Ако това е валидно предположение (т.е. това е единствената възможна причина за повреда), тогава вашият рутер може да се справи с това, като използва dataNotFound кука.

  3. Ако трябва изрично да посочите причината за грешката, разгледайте отблизо примера за „преброяване“ от документите. Можете да декларирате колекция само за клиента, наречена addressErrors и след това да извикате this.added с динамично създаден документ, описващ причината за грешката. Изпълнението на това е малко по-трудно и вероятно заслужава отделен въпрос, ако се затрудните. Ще видя дали първите две имат смисъл, преди да опитам.

person David Weldon    schedule 25.10.2014
comment
Това изглежда добре, но не ми помага. Редактирах публикацията си, за да ви покажа истинския проблем, който имам (имам нужда от асинхронна функция преди аргументи waitOn или метод за синхронизиране от страна на сървъра, но след това трябва да се върна, ако има грешка.) - person TJR; 27.10.2014
comment
Добре, актуализирах отговора с още няколко предложения - надявам се, че едно от тях работи за вас. - person David Weldon; 27.10.2014
comment
Добър вход - отново. Ще проверя това днес и ще ви дам обратна връзка. - person TJR; 27.10.2014
comment
Здравей Дейвид и съжалявам за късния отговор, но не успях да тествам твоите 3 точки. Към точка 1: мога да добавя функция (като onBeforeAction) към маршрут, но това не може да бъде асинхронно, както разбрах? И също така - както знам - няма начин да се извика метод, който се изпълнява от страната на сървъра и да се каже на рутера да изчака, докато резултатът е там, нали? Към точка 2: Това е, което актуализирах и правя сега - така че абонаментът е готов, но не знам защо: Имаше ли грешка или не? Така че това наистина няма да реши проблема, но трябва да се направи! (Благодаря за това). - person TJR; 10.11.2014
comment
Точка 3: Прочетох документацията и това изглежда е опция ... ако има нещо възможно като добавяне на добавено или променено обратно извикване към абонамента със съдържанието му. След това мога да кажа на абоната, че е добавено някакво съдържание (например код за грешка) и това съдържание ще мога да прочета от страна на клиента - но това все още ли е възможно по този начин? Няма обратно извикване за абонамент - вместо това изглежда просто има обратно извикване за колекция, нали? Мисля, че това не е най-доброто решение, но може би единственото, което ще работи все още ... - person TJR; 10.11.2014
comment
Моето предположение за (1) беше, че каквато и форма да е попълнил потребителят преди показване на географските данни, може просто да потвърди данните с извикване на асинхронен метод и да промени маршрута само ако извикването е успешно. На теория можете да потвърдите данните в onBeforeAction кука, като използвате моя код от този проблем. При мен работи в iron-router 0.9.4, но не в 1.0, когато опитах за последен път. - person David Weldon; 10.11.2014