У меня возникли проблемы с настройкой jQueryUI selectmenu в приложении Meteor, когда параметры являются динамическими. Я использую:Как написать jQueryUI selectmenu с динамическими параметрами в шаблон Meteor Blaze
- Meteor 1.4.1
- JQuery 2.2.4
- jQueryUI 1.11.4
- lodash 4.15.0
physiocoder said on a different question «Реактивность сила Метеор, чтобы ты выберите, кто отвечает за обновления DOM ».
Я понимаю, что это имеет основополагающее значение для моей проблемы здесь. Соответственно, нет проблем, если страница/шаблон может позволить Meteor загружать все содержимое/данные страницы, а затем передавать управление DOM в виджеты jQueryUI. Однако у меня есть случай, когда я хочу получить торт и съесть его тоже. Я хочу, чтобы Meteor энергично подавал параметры для виджета jQueryUI (в частности, selectmenu на данный момент), но все же пусть jQueryUI обрабатывает стиль/тематику.
Инициализация виджета jQueryUI в шаблоне onRendered работает отлично, а также уничтожает виджеты jQueryUI, если необходимо, в шаблоне onDestroyed. Вызов selectmenu('refresh')
в функции onRendered шаблона опции обновляет selectmenu, когда доступны новые параметры. Тем не менее, я не могу найти нигде, я могу эффективно вызвать обновление, когда параметры будут удалены, так что selectmenu обновляется до нового правильного состояния пользовательского интерфейса - а не в конце события, которое изменяет контекст данных Meteor, а не в шаблоне опции onDestroyed, а не функция Tracker.autorun, привязанная к соответствующему источнику данных.
HTML:
<head>
<title>Proof of Concept</title>
</head>
<body>
<div id="myApp">
{{> myForm}}
</div>
</body>
<template name="myForm">
<div>
<div id="selectedEntries">
<h3>Selected Entries</h3>
<ul class="display-list">
{{#each entry in selectedEntries}}
{{> myForm_entry entry}}
{{/each}}
</ul>
</div>
<br/>
<form id="includeEntry">
<select name="entryToInclude" id="entryToInclude">
{{#each potentialEntry in availableEntries}}
{{> myForm_option potentialEntry}}
{{/each}}
</select>
<input type="submit" value="Include Entry">
</form>
</div>
</template>
<template name="myForm_entry">
<li>
<div class="button removeEntry" data-id="{{_id}}">X</div>
<span>{{name}}</span>
</li>
</template>
<template name="myForm_option">
<option value="{{_id}}">{{name}}</option>
</template>
JavaScript:
Template.myForm.helpers({
availableEntries: function() {
return _.filter(Session.get('someEntries'), function(o) {
return Session.get('selectedEntryIds').indexOf(o._id) == -1;
});
},
selectedEntries: function() {
return _.filter(Session.get('someEntries'), function(o) {
return Session.get('selectedEntryIds').indexOf(o._id) != -1;
});
}
});
Template.myForm.events({
'submit #includeEntry': function (event) {
event.preventDefault();
if (_.isEmpty(Session.get('selectedEntryIds'))) {
Session.set('selectedEntryIds', [$('#entryToInclude').val()]);
} else {
let selectedEntryIds = Session.get('selectedEntryIds');
selectedEntryIds.push($('#entryToInclude').val());
Session.set('selectedEntryIds', selectedEntryIds);
}
$('#entryToInclude').selectmenu('refresh')
},
'click .removeEntry': function (event) {
event.preventDefault();
let selectedEntryIds = Session.get('selectedEntryIds');
selectedEntryIds = _.pull(selectedEntryIds, $(event.target).parent().attr('data-id'));
Session.set('selectedEntryIds', selectedEntryIds);
}
});
Template.myForm.onCreated(function() {
let someEntries = [{
_id:'1',
name:'One'
},{
_id:'2',
name:'Two'
},{
_id:'3',
name:'Three'
},{
_id:'4',
name:'Four'
},{
_id:'5',
name:'Five'
},{
_id:'6',
name:'Six'
}];
Session.set('someEntries', someEntries);
Session.set('selectedEntryIds', []);
});
Template.myForm.onRendered(function() {
$('#entryToInclude').selectmenu();
$('input:submit').button();
});
Template.myForm_entry.onRendered(function() {
$('.button').button();
});
Template.myForm_option.onRendered(function() {
if ($('#entryToInclude').is(':ui-selectmenu')) {
$('#entryToInclude').selectmenu('refresh');
}
});
Template.myForm_option.onDestroyed(function() {
$('#entryToInclude').selectmenu('refresh');
});
Tracker.autorun(function() {
if (Session.get('selectedEntryIds')) {
if ($('#entryToInclude').is(':ui-selectmenu')) {
$('#entryToInclude').selectmenu('refresh');
}
}
});
#entryToInclude selectmenu продолжает включать запись, которая была только что выбрали; выбор второй записи, пронумерованной как высокий или более высокий, фактически выбирает последующую запись (например, выбор 4, затем 5 фактически выбирает 4 и 6), за исключением того, что выбор последней записи сразу после успешного выбора ничего не делает, кроме обновления selectmenu.