Пробелы Meteor {{#if someCondition}} кратко отображают данные при обновлении страницы

Я пробовал это несколькими разными способами, и оба они ведут себя одинаково (код см. Ниже). Я использую пробел, если условие (и также пытался использовать помощника), чтобы проверить, вошел ли пользователь в систему, а затем отображать ссылки для входа/регистрации, если это не так. Если они есть, спрячьте их.

Что я заметил, так это то, что при начальной загрузке страницы (если они возвращаются с другого сайта) ссылки для входа/регистрации быстро отображаются перед тем, как скрыться (если пользователь все еще вошел в систему). Есть ли способ гарантировать, что никакие элементы не отображаются в представлении, если условие ложно? Мне кажется, что он должен проверять до того, как представление начнет рендеринг, а затем отображать соответствующие элементы на странице.

Спасибо за помощь! -Крис

Решение мерцания, с которым я столкнулся: я сверялся с пользователем, хотя представление отображалось быстрее, чем запрос БД. Я добавил защитное выражение (см. ниже), и это, кажется, позаботилось о мерцании.

isUserLoggedOut: function() {
  var user = Meteor.user();

  if(Meteor.user()) {
    return user && false;
  } else{
    return user && true;
  }
}

Попытка №1:

Template.headerTpl.helpers({
  isUserLoggedIn: function() {
    var user = Meteor.user();

    if(user) {
      return false;
    } else{
      return true;
    }
  }
});

<template name="headerTpl">
  {{#if isUserLoggedIn}}
  <li style="display:none;"><a href="{{pathFor 'userRegistrationFormTpl'}}" id="signup-js">Sign Up</a></li>
  <li><a href="{{pathFor 'userLoginFormTpl'}}" id="login-js">Login</a></li>
  {{/if}}
</template>

Попытка №2:

Template.headerTpl.helpers({
  isUserLoggedIn: function() {
    var user = Meteor.user();

    if(user) {
      return "hide";
    } else{
      return "show";
    }
  }
});

<template name="headerTpl">
  <li class={{isUserLoggedIn}}><a href="{{pathFor 'userRegistrationFormTpl'}}" id="signup-js">Sign Up</a></li>
  <li class={{isUserLoggedIn}}><a href="{{pathFor 'userLoginFormTpl'}}" id="login-js">Login</a></li>
</template>

Попытка №3:

{{#if currentUser}}
{{else}}
<li style="display:none;"><a href="{{pathFor 'userRegistrationFormTpl'}}" id="signup-js">Sign Up</a></li>
<li><a href="{{pathFor 'userLoginFormTpl'}}" id="login-js">Login</a></li>
{{/if}}

Попытка №4:

<template name="headerTpl">
  {{#if isUserLoggedOut}}
    {{> signInLinksTpl}}
  {{/if}}
</template>

<template name="signInLinksTpl">
  <li style="display:none;"><a href="{{pathFor 'userRegistrationFormTpl'}}" id="signup-js">Sign Up</a></li>
  <li><a href="{{pathFor 'userLoginFormTpl'}}" id="login-js">Login</a></li>
</template>

Template.headerTpl.helpers({
  isUserLoggedOut: function() {
    if(Meteor.user()) {
      return false;
    } else{
      return true;
    }
  }
});

person Centinel3    schedule 19.03.2015    source источник


Ответы (3)


Вам необходимо подписаться на коллекцию Meteor.users, шаблон отрисуется после создания Meteor.user(), если вы не будете ждать, страница подписки будет мигать, потому что при запуске в коллекции Meteor.users ничего нет.

Вы можете использовать новую функциональность Meteor в шаблоне, где у вас есть поле для входа

Template.login.onCreated(function () {
  var self = this;

  self.autorun(function () {
    self.subscribe("users");
  });
});

И в HTML

{{#if Template.subscriptionsReady}}
    <!--content-->
{{else}}
    Give me a second...
{{/if}}

Конечно, вам нужно создать публикацию с именем «пользователи».

person sdooo    schedule 19.03.2015
comment
это было оно. Я попробовал несколько из вышеперечисленных решений, но не смог заставить их работать так, как хотел. это решение помогло, не говоря уже об использовании новой технологии Meteor! Ваше здоровье! - person Centinel3; 20.03.2015

Вы уверены, что думаете об этом правильно?

isUserLoggedIn: function() { // implies you're checking for the user
    var user = Meteor.user(); // if there's a user this returns true

    if(user) { // you're saying if there's a user ...
        return false; // return false
    } else{ // and if there isn't
    return true; // return true
    }
}

По сути, вы говорите: «Вошел ли пользователь в систему», и если да, «верните false», что заставляет вас дважды задуматься. Вместо этого измените свою логику.

isUserLoggedOut: function() { // implies you're checking for the user
    var user = Meteor.user(); // if there's a user this returns true

    if(user) { // there is a user
        return false; // so isUserLoggedOut == false
    } else{ // and if there isn't a user
        return true; // isUserLoggedOut == true
    }
}

Теперь ваш шаблон становится простым

{{#if isUserLoggedOut}}
   {{>loggedOutTemplate}}
{{/if}}
person thatgibbyguy    schedule 19.03.2015
comment
Спасибо @thatgibbyguy. Имеет смысл наверняка. Я, безусловно, реализую это, хотя это не меняет того факта, что ссылки по-прежнему ненадолго появляются перед тем, как быть скрытыми. - person Centinel3; 19.03.2015
comment
Хорошо, это вспышка, потому что ваша БД еще не была запрошена. Чтобы исправить вспышку, вы можете попробовать использовать защиту dweldon.silvrback.com/guards или попробовать автозапуск, как указано ниже. Ironrouter также предлагает опцию ожидания, которую я обычно использую, чтобы избежать флэш-памяти. - person thatgibbyguy; 20.03.2015

Вместо этого вы можете использовать помощник currentUser из пакета учетных записей, например.

{{#if currentUser}}
<!-- show content -->
{{else}}
 {{> login }} <!-- render login template -->
{{/if}}

Железный маршрутизатор.

Существует также решение на уровне маршрутизатора с использованием Router.onBeforeAction.

// lib/routes.js
// Create the function to check login.
   var requireLogin = function() {
       if (! Meteor.user()) {
          this.render('login');
        } else {
          this.next(); //using this.next the iron router will render the route named on the onBefore
      }
   }

   Router.onBeforeAction(requireLogin, {only: 'theRoute});

ОБНОВЛЕНИЕ

Template.headerTpl.helpers({
  isLogged:function(){
   if(Meteor.user()){
      return true;
    }else{
      return false;
    }
  }
})

<template name="headerTpl">
  {{#if isLogged}}
       <h1>Welcome User</h1>
     {{else}}
       <li style="display:none;"><a href="{{pathFor 'userRegistrationFormTpl'}}" id="signup-js">Sign Up</a></li>
       <li><a href="{{pathFor 'userLoginFormTpl'}}" id="login-js">Login</a></li>
  {{/if}}
</template>
person Ethaan    schedule 19.03.2015
comment
Итан получил его раньше меня. Логика здесь заключается в том, что если есть пользователь, покажите ему пользовательский контент, если не попросите его войти в систему. - person thatgibbyguy; 19.03.2015
comment
Спасибо @Ethaan, но ваше решение — это моя попытка №3 (см. выше), которая ведет себя так же. ссылки отображаются быстро, прежде чем они будут скрыты, как только приложение поймет, что пользователь вошел в систему. - person Centinel3; 19.03.2015
comment
@Centinel3, ты пробовал onBefore? - person Ethaan; 19.03.2015
comment
Я не отображаю шаблон, я показываю/скрываю ссылки внутри шаблона. Ссылки находятся в разделе заголовка веб-приложения, поэтому весь шаблон отображается, а затем проверяет, вошел ли пользователь в систему, прежде чем предоставлять ссылки. Полагаю, я мог бы удалить ссылки и поместить их в собственный шаблон и посмотреть, сработает ли это, хотя мне это кажется безумием. Я немного попробую. - person Centinel3; 19.03.2015
comment
@Centinel3 помощник currentUser должен работать, но проверьте обновление ответа - person Ethaan; 19.03.2015
comment
Использование отдельного шаблона имеет такое же поведение. Я вижу ссылку ненадолго, прежде чем она исчезнет. - person Centinel3; 19.03.2015
comment
Я попробовал новый шаблон и все еще вижу, что ссылки мигают, прежде чем они будут скрыты. Я отредактировал свой первоначальный вопрос выше с помощью попытки № 4 (также реализовал рефакторинг @thatgibbyguy - person Centinel3; 19.03.2015