2016-07-29 2 views
0

У меня есть несколько «множественных» селекторов, но, ради этого примера, допустим, у меня два.Как я могу сделать этот код Метеор реактивным?

<form class="input-field col s10"> 
    <select multiple id="jans-room21"> 
    <option value="" disabled selected>Add Names</option> 
    {{#each Jans21}} 
     <option value= '{{FullName}}' selected = {{formatSelectedNames21 RoomJans}} >{{FullName}}</option> 
    {{/each}} 
    </select> 
</form> 

<form class="input-field col s10"> 
    <select multiple id="jans-room22"> 
    <option value="" disabled selected>Add Names</option> 
    {{#each Jans22}} 
     <option value='{{FullName}}' selected = {{formatSelectedNames22 RoomJans}}>{{FullName}}</option> 
    {{/each}} 
    </select> 
</form> 

Jans21 и Jans22 возвращают ряд документов из БД. Они будут отображать выбранные имена для этой комнаты или те, у которых нет свойства «RoomJans», или «RoomJans» равно «». Они будут исключать те имена, которые были выбраны в другом селекторе.

Template.jansNameSelect.helpers({ 
    Jans21: function() { 
    return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['21A', '21B'] }}]}]}, { sort: { FullName: 1 }}).fetch(); 
    }, 

    Jans22: function() { 
    return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['22A', '22B'] }}]}]}, { sort: { FullName: 1 }}).fetch(); 
    } 
}); 

При нажатии кнопки вызывается метод для обновления БД и сохранения этих имен.

// ... 
$('#room_21_jans_button').on('click', function() { 
var roomValue = $('input[name="room_select_21_jans"]:checked').val(); 
if (roomValue) { 
    var selectedValues = []; 
    $r21jans.find("option:selected").each(function() { 
    selectedValues.push($(this).val()); 
    }); 
    selectedValues.splice(0, 1); 
    var unselectedValues = []; 
    $r21jans.find("option:not(:selected)").each(function() { 
    unselectedValues.push($(this).val()); 
    }); 
    Meteor.call('roomUpdateSN', 
    selectedValues, 
    unselectedValues, 
    roomValue, 
    Session.get('GlobalCurrentCampYear') 
); 
//... 

То, что я после, когда имена выбраны в первом селекторе, а затем сохраняются в базе данных, второй селектор будет обновлять свой список имен, чтобы удалить эти имена, которые были выбраны из первых. Я думал, что это будет реактивно, поскольку я выполняю действие базы данных, так что функция «Jans22» снова загорится, если имена будут выбраны из первого селектора и сохранены в БД. Но это не так. Однако он будет загружать правильные имена при обновлении. Есть ли способ заставить это быть реактивным?

+0

Ваш код выглядит так, как будто он должен реагировать на первый взгляд. Используете ли вы компонент пользовательского интерфейса, который манипулирует выбором после его рендеринга? Если это так, вероятно, потребуется обновление после обновления параметров. –

+0

Подумайте об этом, я использую селектор Materialize. Интересно, не ответят ли эти селекторы на реактивность Метеор? –

ответ

1

При использовании инфраструктуры компонентов пользовательского интерфейса поверх шаблонов Meteor вам необходимо указать структуру, когда шаблон под ней изменился. Это связано с тем, что в структуре (материализуется в этом случае) используется <select>, отображаемый шаблоном в качестве ввода, а затем создается новый набор элементов DOM для визуализации желаемого пользовательского интерфейса. Если изменение <option>, вам нужно сообщить инфраструктуре повторно запустить этот процесс.

В этом случае вам необходимо повторно запустить

$('select').material_select(); 

каждый раз, когда есть изменения. Самый простой способ сделать это, на мой взгляд, - использовать отложенную функцию от самого помощника:

Template.jansNameSelect.helpers({ 
    Jans21: function() { 
    Meteor.defer(function() { $('select#jans-room21').material_select(); }); 
    return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['21A', '21B'] }}]}]}, { sort: { FullName: 1 }}).fetch(); 
    }, 

    Jans22: function() { 
    Meteor.defer(function() { $('select#jans-room22').material_select(); }); 
    return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['22A', '22B'] }}]}]}, { sort: { FullName: 1 }}).fetch(); 
    } 
}); 
+0

Вау, ты прав. Я только инициализировал селектор один раз при визуализации шаблона. Кажется, однако, что повторный запуск пользовательского интерфейса должен появиться ПОСЛЕ возврата Programs.find(), который не будет работать после того, как код не вернется. Ожидается ли запуск Meteor.defer после возвращения функции Jans21? –

+0

Точно. Он будет запущен после завершения всех запланированных событий (включая повторный рендеринг). –

+0

Есть ли какое-либо преимущество для запуска, $ ('select # jans-room21'). Material_select() внутри метода отложенности, а не просто $ ('select'). Material_select()? Оба, похоже, выполняют эту работу. –

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