2014-02-04 3 views
0

В моем приложении, использующем MeteorJS У меня есть ситуация, когда мне приходится подписываться на «несколько аспектов» одной коллекции.Meteor view не обновляется в IE

У меня есть коллекция под названием Invitations, а на главной странице я подписываюсь на публикацию, в которой публикуются те Invitations, где InvitedUser является текущим пользователем.

Тогда в модальном диалоге я хочу управлять теми Invitations, которые отправил от текущего пользователя. Я не хочу подписываться на изменения отправленного Invitations только в этом диалоговом окне.

Итак, я решил вручную подписаться на публикацию, когда диалог отображается пользователю и прекращает подписку, когда модаль закрывается.

Код позади для модального диалога выглядит следующим образом: (. Я ушел из несущественных деталей)

var subscriptionHandle; 

Template.invitationsModal.helpers({ 
    invitations: function() {  
     var activeGroupId = Session.get('activeGroupId'); 
     var filter = activeGroupId ? {invitedBy: Meteor.user()._id, group: activeGroupId} : {}; 
     return Invitations.find(filter); 
    } 
}); 


Template.invitationsModal.rendered = function() { 
    $('#invitationsModal').off('shown.bs.modal').on('shown.bs.modal', function(e) { 
     var activeGroupId = Session.get('activeGroupId'); 
     subscriptionHandle = Meteor.subscribe('sentInvitations', activeGroupId);  
    }); 
    $('#invitationsModal').off('hidden.bs.modal').on('hidden.bs.modal', function(e) { 
     subscriptionHandle.stop(); 
    }); 
}; 

В шаблоне я просто итерацию через invitations помощника:

<template name="invitationsModal"> 
    <div id="invitationsModal" class="modal fade"> 
     <div class="modal-dialog"> 
      <div class="modal-content"> 
       <form role="form" class="form-horizontal">      
        <div class="modal-header"> 
         <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 
         <h4 class="modal-title">Invitations</h4> 
        </div> 
        <div class="modal-body container-fluid"> 
         {{#each invitations}} 
          {{> invitationRow}} 
         {{/each}} 
         <div class="form-group"> 
          <div class="col-xs-offset-2 col-xs-6"> 
           <input type="text" class="form-control" name="name" placeholder="Name or email"> 
          </div>        
          <div class="col-xs-2"> 
           <input type="submit" class="btn btn-default button-add" value="Invite" /> 
          </div> 
         </div> 
        </div> 
        <div class="modal-footer"> 
         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
        </div> 
       </form> 
      </div> 
     </div> 
    </div> 
</template> 

Этот шаблон далее входит в состав моей основной страницы:

{{> invitationsModal}} 

Когда я впервые загружаю страницу, переменная сеанса activeGroupId пуста, поэтому неверные данные загружаются в скрытый модальный. Когда я показываю модальный пользователю, я установил activeGroupId до некоторого значения, так:

  1. в invitations помощника снова выполняется из-за этого изменения, и теперь мы возвращаем действительный список приглашений для активного группа.

  2. в DOM обновляется внутри модального, чтобы отразить изменения в 1.)

Сейчас здесь идет интересная часть: все решение отлично работает на Chrome и Firefox, но не всегда на IE.

В IE есть один случай, когда 1.) шаг выполняется правильно, но 2.) просто не выполняется.

Это тот случай, когда я впервые открываю модальный режим. На этот раз DOM содержит неправильную, нефильтрованную коллекцию.

Когда я закрываю и открываю модальный во второй раз (без обновления страницы в браузере), он снова работает отлично.

Я не знаю, что может вызвать подобное поведение. Может быть, это ошибка в Метеор?

(Испытано в IE11)

ответ

0

Вызов Deps.flush() волшебно решить эту проблему - это обработчик события, который показывает диалог с пользователем:

'click .menu-command-invitations': function(e) { 
    Session.set('activeGroupId', this._id); 
    Deps.flush(); // without this, it won't work in IE 
    $('#invitationsModal').modal('show'); 
    e.preventDefault(); 
} 

От Meteor docs:

Depsflush заставляет все готовые реактивные обновления завершать. Например, если обработчик события изменяет переменную сеанса, которая будет вызывать часть пользовательского интерфейса для переименования, обработчик может вызвать заподлицо для немедленного выполнения переиздания, а затем получить доступ к итоговой DOM .

Хотя я действительно не знаю, зачем мне это нужно и почему это не работает только под IE.

Я читаю и записываю переменные сеанса внутри других обработчиков событий в одном приложении, и они отлично работают в IE.

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