Полимер 1.0: Двусторонние крепления с входными элементами
Код
Рассмотрим следующий пользовательский элемент Polymer:
<dom-module id="test-element">
<template>
<input type="text" value="{{value}}">
<button>Reset</button>
</template>
<script>
Polymer({
is: 'test-element',
properties: {
'value': {
type: String,
reflectToAttribute: true,
notify: true,
value: null
}
}
});
</script>
</dom-module>
Я использую этот пользовательский элемент в своем index.html следующим образом:
<html>
<head>
<script type="text/javascript" src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="test-element.html">
<title>Test App</title>
</head>
<body>
<test-element value="test"></test-element>
</body>
</html>
Вопрос
Я считаю, что я объявил свойство value
как двухстороннее связывание (notify: true
); но когда я нажимаю на ввод и набираю текст (например, "foo"
), он не отражается в модели (т.е. вызов document.querySelector('test-element').value
возвращает значение, установленное в index.html, "test"
). Интересно, что атрибут value
ввода изменяется правильно, но свойство value моего тестового элемента не работает. Что мне не хватает?
Я также должен отметить, что вызов document.querySelector('test-element').setAttribute('value', 'bar')
работает правильно.
Ответы
Ответ 1
Сначала обратите внимание, что поля notify
и reflectToAttribute
в свойстве value
указывают, как реагировать на него родительский, а не на то, как привязываться к ребенку.
IOW, notify: true
означает сделать value
двусторонней связью извне, а не изнутри. reflectToAttribute: true
сообщает Polymer записывать value
в атрибут каждый раз, когда он изменяется (не подходит для производительности).
Когда вы выполняете привязку как <x-element foo="{{value}}">
, это x-элемент, который решает, является ли foo
двусторонней связующей.
Нативные элементы, такие как input
, не имеют встроенной поддержки двусторонней привязки, вместо этого используют синтаксис событий-наблюдателя Polymer для двусторонней привязки к вводу. Вот так
<input value="{{value::change}}">
.
Это говорит Polymer обновлять this.value
от input.value
всякий раз, когда input
запускает событие change
.
Ответ 2
Вам нужно изменить это:
<input type="text" value="{{value}}">
в
<input type="text" value="{{value::input}}">
попробуйте здесь. Это говорит о том, что полимер прослушивает входные события. Объяснено здесь (не очень понятно ИМО).
Ответ 3
Как упоминалось Андреем и Скоттом Майлсом, оба этих решения будут работать, чтобы получить двухстороннюю привязку с встроенным ящиком ввода HTML.
<input type="text" value="{{value::input}}">
<input type="text" value="{{value::change}}">
С важным отличием:
:: изменение будет срабатывать только при нажатии текстового поля на фокус или ввод.
:: ввод будет срабатывать при каждом нажатии клавиши.