【发布时间】:2018-05-09 20:20:56
【问题描述】:
我有一个用于接收用户输入的搜索输入字段和一个响应用户输入的可变状态按钮。注意搜索输入上的on-input 事件。
<dom-module id="app-search">
<template>
<input type="search" id="searchInput" on-input="_onInput" />
<!-- NOTE: button is set to 'disabled' when there is no value of search field -->
<paper-button disabled>Done</paper-button>
</template>
</dom-module>
在 Polymer ready() 定义中,我得到了 paper-button 元素的句柄(ready() 函数在所有内容之后调用,包括在元素及其属性已初始化之后,因此现在是查询本地 DOM)。
ready() {
super.ready(); // must call this for Polymer to work
// get handle to paper-button element
this._doneBtn = Polymer.dom(this.root).querySelector('paper-button');
}
(顺便说一下,我知道使用this.$ 可以用作Polymer.dom(this.root).querySelector() 的语法快捷方式,但该语法似乎只适用于定位本地DOM 中具有id,例如:this.$.searchInput 将返回带有 id="searchInput" 的元素的句柄。有谁知道无需输入 Polymer.dom(this.root)... 即可定位非 id 常规元素的速记 ?)
我有一个函数可以在搜索字段中检测input 事件。如果搜索字段中有值,请启用该按钮。
_onInput() {
// if search input has value
if (Boolean(this.$.searchInput.value)) {
// remove disabled attr from button
this._doneBtn.removeAttribute('disabled');
} else {
this._disableBtn();
}
}
_disableBtn() {
this._doneBtn.setAttribute('disabled', true);
}
到目前为止,这可以在用户开始输入时启用按钮;当没有值时,按钮将被禁用。
不过,按照惯例,用户也可以通过点击搜索输入右侧的小“x”来删除输入值。开发人员可以通过将search 事件附加到输入元素来检测该事件:
ready() {
super.ready(); // must call this for Polymer to work
// get handle to paper-button element
this._doneBtn = Polymer.dom(this.root).querySelector('paper-button');
// attach 'search' event listener to search input field
// call the element's '_disableBtn' function
this.$.searchInput.addEventListener('search', this._disableBtn);
}
问题是,当我通过单击搜索字段有值时出现的“x”触发事件时,this._disableBtn 函数会触发,但函数内部的this._doneBtn 返回未定义:
Uncaught TypeError: Cannot read property 'setAttribute' of undefined.
假设这可能与不正确的类型定义有关,我尝试在 Polymer 属性 getter 中声明 _doneBtn 属性:
static get properties() {
return {
_doneBtn: Object // also tried 'String'
}
}
我还尝试再次从 _disabledBtn 函数内部查询 DOM 并尝试重新声明该属性,但仍然遇到相同的错误:
_disableBtn() {
if (!this._doneBtn) {
this._doneBtn = Polymer.dom(this.root).querySelector('paper-button');
}
this._doneBtn.setAttribute('disabled', true);
}
谁能理解这里发生了什么?这似乎与事件监听器有关。尽管在 ready() 调用中切换声明的顺序并没有什么不同,但也许 DOM 在解析之前并未完全呈现?它也可能与this 有关。
有趣的是,当我在_disableBtn 中使用console.log(this) 时,控制台会返回两个不同的this 实例,一个用于宿主元素(<app-search>),另一个用于触发事件的目标元素:two elements point to 'this'。另外值得注意的是this的打印顺序。
我希望比我更聪明的人可以帮助解决这里发生的事情。
【问题讨论】:
标签: javascript events polymer dom-events polymer-2.x