Почему я получаю неопределенное значение после перезагрузки страницы в Meteor?

Итак, у меня есть следующая форма:

template(name='editUser')
  .row
    .col-md-4.col-md-offset-4
      .page-header
        h1 Edit user
      form#edit-user-form
        .form-group
          label(for='name') Name
          input#user-name.form-control(type='text' placeholder='Name' value='{{user.name}}')
        .form-group
          label(for='email') E-Mail
          input#user-email.form-control(type='text' placeholder='E-Mail' value='{{getEmail user}}')
    button.btn.btn-primary(type='submit') Update

следующий handlebars.js-Helper:

Handlebars.registerHelper('getEmail', function (user) {
  if (user.emails && user.emails[0] && user.emails[0].address)
    return user.emails[0].address;
  return '';
  });

и следующий код железа-маршрутизатора:

    EditUserController = RouteController.extend({
      template: 'editUser',
      waitOn: function () {
        return Meteor.subscribe('user', this.params._id);
      },
      data: function () {
        return {
          user: Meteor.users.findOne( { _id: this.params._id } )
        };
      }
});

Если я запущу свое приложение и нажму на ссылку на форму редактирования пользователя, я увижу адрес электронной почты. Но если я изменю свой код, и Meteor автоматически обновит страницу, поле электронной почты будет пустым, а консоль скажет, что не может получить значение undefined.

Если я использую ту же форму, но с with-Helper, электронная почта отображается, даже если Meteor автоматически обновляет страницу:

template(name='editUser')
  .row
    .col-md-4.col-md-offset-4
      .page-header
        h1 Edit user
      form#edit-user-form
        with user
          .form-group
            label(for='name') Name
            input#user-name.form-control(type='text' placeholder='Name' value='{{name}}')
          .form-group
            label(for='email') E-Mail
            input#user-email.form-control(type='text' placeholder='E-Mail' value='{{getEmail this}}')
      button.btn.btn-primary(type='submit') Update

Почему это так? И должен ли я всегда использовать with-Helper, если я получаю одиночные результаты (только один результат для отображения)?

Заранее спасибо!


person pmuens    schedule 14.04.2014    source источник


Ответы (1)


Замените Meteor.users.findOne на Meteor.users.find.

Когда findOne ничего не находит, возвращается undefined, что вызывает вашу ошибку; когда find ничего не находит, возвращает пустой курсор, с которым Meteor знает, что делать. По сути, все, что вы делали, добавляя with, — это заставляло Meteor проверять, не определено ли значение, но эта проверка не нужна для курсора, пустого или иного.

person Geoffrey Booth    schedule 15.04.2014
comment
Большое спасибо за ваш ответ! Поэтому рекомендуется использовать find() вместо findOne. Можете ли вы сказать, когда я должен использовать find() и когда я должен использовать findOne()? Заранее спасибо! - person pmuens; 15.04.2014
comment
Вы можете использовать findOne где угодно, часто это удобнее, чем find; просто знайте, что когда вы его используете, вам нужно проверить возможность возврата undefined, когда он ничего не находит. В этом конкретном случае each жалуется, когда вы отправляете ему undefined, но не когда вы отправляете ему пустой курсор, поэтому проще использовать find. В качестве альтернативы вы можете использовать findOne, но затем проверить, что это undefined, прежде чем возвращать результаты в each, и изменить значение результатов с undefined на [] (пустой массив), чтобы избежать ошибки. - person Geoffrey Booth; 15.04.2014
comment
Также обратите внимание, что при использовании find, если вам действительно нужен только один результат, вы должны добавить limit: 1 в запрос, если только вы не знаете, что он никогда не вернет более одного (например, вы ищете _id). - person Geoffrey Booth; 15.04.2014