Vaadin ComboBox Не удается прочитать свойство 'addEventListener' со значением NULL
Я пытаюсь добавить прослушиватель событий для отображения изображения, основанного на том, какой шаблон выбран в Vaadin ComboBox. Для этого я хотел бы иметь прослушиватель событий, который... Когда значение ComboBox изменено, найдите в файле JSON путь к изображению и отобразите выбранное изображение в заполнителе div.
Я еще не создал решение для этого уровня, так как у меня проблема с моим селектором запросов. Из того, что я понимаю, он не может создать переменную combobox, поэтому обработчик событий не добавляется в combobox, потому что он не существует.
Вывод ошибки при загрузке страницы:
Uncaught TypeError: Cannot read property 'addEventListener' of null
Код для проекта:
<div id="patternSelect">
<template is="dom-bind" id="paver">
<div class="fieldset">
<vaadin-combo-box id="cb1" label="Pattern" class="patterns" items="[[patterns]]"></vaadin-combo-box>
<br>
<vaadin-combo-box id="cb2" label="Color" class="colors" items="[[colors]]"></vaadin-combo-box>
</div>
</template>
</div>
<script type="text/javascript">
$( document ).ready(function() {
var combobox = document.querySelector('#cb1');
combobox.addEventListener('value-changed', function(event) {
console.log(event.detail.value);
});
combobox.addEventListener('selected-item-changed', function(event) {
console.log(event.detail.value);
});
});
</script>
1 ответ
Поскольку поля со списком вложены в template
тег:
<template is="dom-bind" id="paver">
содержимое этого шаблона недоступно до тех пор, пока он не будет активирован и, следовательно, добавлен в DOM, взгляните на это руководство.
Vaadin / Polymer будет просматривать эти шаблоны при загрузке и активировать их, поэтому, когда вы запускаете свой код, он выглядит так, как будто это действие еще не выполнено - вызывая ваше document.querySelector('#cb1')
возвращать null
,
Грубый обходной путь заключается в том, чтобы обернуть ваш код слушателя в тайм-аут, и все работает хорошо:
$( document ).ready(function() {
addListenersDelayed()
});
});
function addListenersDelayed(){
setTimeout( function(){
addListeners();
}, 1000)
};
function addListeners(){
combobox.addEventListener('value-changed', function(event) {
console.log(event.detail.value);
});
combobox.addEventListener('selected-item-changed', function(event) {
console.log(event.detail.value);
});
}
Другой способ заключается в использовании обратных вызовов Polymer для образа жизни:
// select your template
var paver = document.querySelector('#paver');
// define the ready function callback
paver.ready = function () {
// use the async method to make sure you can access parent/siblings
this.async(function() {
// access sibling or parent elements here
var combobox = document.querySelector('#cb1')
combobox.addEventListener('value-changed', function(event) {
console.log(event.detail.value);
});
combobox.addEventListener('selected-item-changed', function(event) {
console.log(event.detail.value);
});
});
};
Опасность этого заключается в том, что компонент становится готовым до регистрации обратного вызова. По сути, оба метода обеспечивают доступность DOM шаблонов при выполнении кода.