Vaadin ComboBox 无法读取 属性 'addEventListener' 的 null

Vaadin ComboBox Cannot read property 'addEventListener' of 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>

由于组合框嵌套在 template 标记中:

<template is="dom-bind" id="paver">

此模板的内容在被激活并因此添加到 DOM 之前无法访问,看看这个 tutorial

Vaadin/Polymer 将在加载时查看这些模板并激活它们,因此当您 运行 您的代码看起来好像此操作尚未完成 - 导致您的 document.querySelector('#cb1') return 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 lifestyle callbacks:

// 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 可用。