我怎样才能使这个 Meteor 代码具有反应性?
How could I make this Meteor code reactive?
我有很多 'multiple' 选择器,但为了这个例子,假设我有两个。
<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' 函数将再次触发。但事实并非如此。但是,它将在刷新时加载正确的名称。有没有办法让它变得被动?
在 Meteor 模板之上使用 UI 组件框架时,您需要在其下方的模板发生更改时通知框架。这是因为框架(在这种情况下实现)使用模板呈现的 <select>
作为输入,然后创建一组新的 DOM 元素来呈现所需的 UI 外观-和感觉。如果<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();
}
});
我有很多 'multiple' 选择器,但为了这个例子,假设我有两个。
<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' 函数将再次触发。但事实并非如此。但是,它将在刷新时加载正确的名称。有没有办法让它变得被动?
在 Meteor 模板之上使用 UI 组件框架时,您需要在其下方的模板发生更改时通知框架。这是因为框架(在这种情况下实现)使用模板呈现的 <select>
作为输入,然后创建一组新的 DOM 元素来呈现所需的 UI 外观-和感觉。如果<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();
}
});