Пакет счетов Meteor.js [дубликат]

Причина:

Причина, по которой это undefined, заключается в том, что вы выполняете асинхронную операцию. Это означает, что потребуется некоторое время, чтобы закончить метод getEventList (в зависимости от скорости вашей сети).

Итак, посмотрим на http-вызов.

this.es.getEventList()

После вас на самом деле сделать («пожар») ваш запрос http с subscribe, вы будете ждать ответа. Во время ожидания javascript выполнит строки под этим кодом, и если он встретит синхронные назначения / операции, он немедленно их выполнит.

Итак, после подписки на getEventList() и ожидания ответа,

console.log(this.myEvents);

строка будет выполнена немедленно. И значение этого параметра - undefined до того, как ответ поступит с сервера (или во все, что вы его инициализировали в первую очередь).

Это похоже на выполнение:

ngOnInit(){
    setTimeout(()=>{
        this.myEvents = response;
    }, 5000);

    console.log(this.myEvents); //This prints undefined!
}

Решение:

Итак, как мы можем преодолеть эту проблему? Мы будем использовать функцию обратного вызова, которая является методом subscribe. Потому что, когда данные поступают с сервера, они будут внутри subscribe с ответом.

blockquote>

Поэтому изменение кода на:

this.es.getEventList()
    .subscribe((response)=>{
        this.myEvents = response;
        console.log(this.myEvents); //<-- not undefined anymore
    });

будет печатать ответ .. через некоторое время. Что вы должны делать:

В вашем ответе может быть много чего другого, кроме как его регистрация; вы должны делать все эти операции внутри обратного вызова (внутри функции subscribe), когда данные поступают.

Еще одна вещь, которая стоит упомянуть, состоит в том, что если вы исходите из фона Promise, then обратный вызов соответствует subscribe с наблюдаемыми. Что вам не следует делать:

Не следует пытаться изменить операцию async на операцию синхронизации (но не на то, что вы можете). Одной из причин, по которым мы имеем асинхронные операции, является то, что пользователь не должен ждать завершения операции, пока они могут делать другие вещи за этот период времени. Предположим, что одна из ваших операций async длится 3 минуты, если у нас не было асинхронных операций, интерфейс застыл в течение 3 минут.


Рекомендуемое чтение:

Оригинальный кредит на этот ответ: Как вернуть ответ от асинхронного вызова?

Но с выпуском angular2 мы были введены для машинописных и наблюдаемых данных, поэтому этот ответ можно надеяться охватывает основы обработки асинхронного запроса с помощью наблюдаемых.

33
задан HGandhi 31 October 2012 в 07:42
поделиться

3 ответа

Справа от Метеорная документация :

Meteor.publish("userData", function () {
    return Meteor.users.find({_id: this.userId},
        {fields: {'other': 1, 'things': 1}});
});

А также:

Meteor.publish("allUserData", function () {
    return Meteor.users.find({}, {fields: {'nested.things': 1}});
});

Надеюсь, это поможет.

47
ответ дан jtblin 21 August 2018 в 01:41
поделиться
  • 1
    Вы знаете, что я попробовал это пять минут назад, и это не сработало, поэтому я задал этот вопрос. Я попробовал еще раз, и вдруг это сработает. Упреки для вас! – HGandhi 31 October 2012 в 07:55
  • 2
    Эй, я пытаюсь, чтобы мой клиент js subscribe был userData, но мне тяжело. Может быть, потому, что у меня нет четкого понимания концепции метеор. Как мне установить его на стороне клиента? – user482594 10 November 2012 в 10:02

Как упоминалось выше, функции публикации

Meteor.publish("userData", function () {
    return Meteor.users.find({_id: this.userId},
        {fields: {'other': 1, 'things': 1}});
});

и

Meteor.publish("allUserData", function () {
  return Meteor.users.find({}, {fields: {'nested.things': 1}});
});

будут вытеснять данные из коллекции Users.

Подписать с

Tracker.autorun(function () {
    Meteor.subscribe("userData");
    Meteor.subscribe("allUserData");
});

И дополнительные данные автоматически войдут в коллекцию Users и будут доступны в объекте Meteor.user().

32
ответ дан colllin 21 August 2018 в 01:41
поделиться
  • 1
    В документации Meteor не упоминаются подписчики. Спасибо за совет! – hsribei 8 June 2013 в 09:19
  • 2
    Метеоритные документы также не упоминают autosubscribe один бит. Это устарело? – Jonathan Dumaine 14 October 2013 в 09:48
  • 3
    Meteor.autosubscribe был заменен Meteor.autorun, а позже Deps.autorun. Я отредактировал ответ, чтобы избежать путаницы. – Dan Dascalescu 26 February 2014 в 14:22
  • 4
    Я новичок в Meteor, и я не могу получить способ доступа к данным после подписки. Я публикую всех пользователей из Meteor.users.find (), и после того, как я подписался на него в клиенте, я не уверен, как мне получить доступ к нему. Я попытался снова с Meteor.users.find (), но я получаю только текущего пользователя. – Neli Chakarova 26 November 2016 в 20:06

Моя история с этим: я продолжил, как говорит документация, но столкнулся с странным поведением. У меня была функция публикации, где я опубликовал весь профиль и объект электронной почты для текущего пользователя (скажем, userData) и просто некоторое подмножество для других пользователей (allUserData).

Когда у меня было -

Meteor.subscribe("allUserData");
Meteor.subscribe("userData");

На стороне клиента сразу после входа пользователя я получил только данные allUserData. Это означает даже для моего зарегистрированного пользователя (этот пользователь не мог видеть свой собственный адрес электронной почты). Когда я обновляю браузер, ошибка была исправлена, и я получил allUserData для всех пользователей, кроме одного входа в систему, у которого есть свой userData (с указанным адресом электронной почты).

Что интересно, если я изменил последовательность этих подписчиков, исправлена ​​ошибка .:

Meteor.subscribe("userData");    
Meteor.subscribe("allUserData");

Ввод в Meteor.autosubscribe(function () { }) ничего не изменил. Наконец, я попытался включить эту подписку в Deps.autorun(function() { }) и явно добавить реактивность, и проблема с последовательностью была решена ..:

Deps.autorun(function() {
  Meteor.subscribe("allUserData", Meteor.userId());
  Meteor.subscribe("userData", Meteor.userId());
  // or
  // Meteor.subscribe("userData", Meteor.userId());
  // Meteor.subscribe("allUserData", Meteor.userId());
}); 

В функции публикации я просто заменяю this.userId на userId из параметра.

Со следующей ошибкой, с которой я столкнулся, был тот, что у меня есть секретный объект systemData в объекте пользователя профиля, который может видеть только администраторов, а не регулярно регистрироваться в пользователях. Но хотя правильный набор функции публикации с 'profile.systemData': 0, этот секретный объект мог видеть всех зарегистрированных пользователей, которые рассматривали его объект профиля. Вероятно, это потому, что мои функции публикации каким-то образом мешали функции публикации в пакете Meteor Account:

// Publish the current user's record to the client.
Meteor.publish(null, function() {
 if (this.userId) {
   return Meteor.users.find(
     {_id: this.userId},
     {fields: {profile: 1, username: 1, emails: 1}});
 } else {
   return null;
 }
}, /*suppress autopublish warning*/{is_auto: true});

В любом случае я разрешил ее с помощью метода Account.onCreateUser() и добавил systemData рядом с объектом профиля, а не в профиль. Там начинаются мои другие проблемы :) см. Обратный вызов Meteor.loginWithPassword не предоставляет пользовательский объект в учетных записях пользователей doc

PS: Если бы я знал это с самого начала, я поставил systemData объект в специальную коллекцию.

4
ответ дан Community 21 August 2018 в 01:41
поделиться
  • 1
    Публикация на стороне сервера не реагирует, сервер будет просто публиковать данные в соответствии со значением, содержащимся в this.userId, во время публикации. Если вы вошли в систему, на стороне сервера нет уведомлений, которые скажут, что this.userId изменен. По этой причине клиент должен повторно подписаться после входа в систему. Это то, что происходит в ответ на то, что вы указываете Meteor.userId () в пределах области подписки Deps.autorun, в это время сервер будет иметь пользовательский идентификатор соответствующего клиента под this.userId. – Flavien Volken 19 November 2014 в 14:10
Другие вопросы по тегам:

Похожие вопросы: