У меня есть поле ввода для поиска ввода пользователя и кнопка с переменным состоянием, которая реагирует на ввод пользователя. Обратите внимание на событие 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()
вызывается после всего, в том числе после инициализации элемента и его свойств, поэтому самое время запросить местный ДОМ).
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)...
?)
У меня есть функция, которая обнаруживает 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);
}
До сих пор это работало так, что, когда пользователь начинает печатать, кнопка становится активной; когда значение отсутствует, кнопка отключается.
Однако, по соглашению, пользователи также могут удалить введенное значение, щелкнув маленькую букву «х», которая появляется справа от входных данных поиска. Разработчики могут обнаружить это событие, прикрепив событие 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: Невозможно прочитать свойство 'setAttribute' из неопределенного .
Предполагая, что это может быть связано с неправильным определением типа, я попытался объявить свойство _doneBtn
в получателе свойств Polymer:
static get properties() {
return {
_doneBtn: Object // also tried 'String'
}
}
Я также попытался снова запросить DOM из функции _disabledBtn
и попытаться повторно объявить свойство, но я все еще получаю ту же ошибку:
_disableBtn() {
if (!this._doneBtn) {
this._doneBtn = Polymer.dom(this.root).querySelector('paper-button');
}
this._doneBtn.setAttribute('disabled', true);
}
Кто-нибудь может понять, что здесь происходит? Похоже, это как-то связано со слушателем событий. Возможно, DOM не полностью обработан до его анализа, хотя переключение порядка объявлений в вызове ready()
не имеет значения? Это может также иметь отношение к this
.
Интересно, что когда я console.log(this)
внутри _disableBtn
, консоль возвращает два разных экземпляра this
, один для элемента host (<app-search>
) и один для целевого элемента, вызвавшего событие: two элементы указывают на «это» . Также примечателен порядок печати this
.
Я надеюсь, что кто-то умнее меня сможет помочь решить, что здесь происходит. Спасибо.