Polymer 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>

I use this custom element in my index.html as follows:

<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') работает правильно.


person Andre Gregori    schedule 14.06.2015    source источник


Ответы (3)


Во-первых, обратите внимание, что поля notify и reflectToAttribute в свойстве value сообщают ему, как реагировать на его родителя, а не о том, как привязываться к дочернему элементу.

IOW, notify: true означает сделать value двусторонней привязкой снаружи, а не изнутри. reflectToAttribute: true говорит Polymer записывать value в атрибут каждый раз, когда он изменяется (не очень хорошо для производительности).

Когда вы выполняете привязку, такую ​​как <x-element foo="{{value}}">, именно x-element решает, является ли foo двусторонней привязкой.

Нативные элементы, такие как input, не имеют встроенной поддержки двусторонней привязки, вместо этого используют синтаксис наблюдателя событий Polymer для двусторонней привязки к входу. Вот так <input value="{{value::change}}">.

Это говорит Polymer обновлять this.value с input.value всякий раз, когда input запускает событие change.

person Scott Miles    schedule 14.06.2015
comment
Спасибо. Различие внутри и снаружи теперь имеет для меня смысл. Я запросил редактирование, добавив ссылку на документацию. - person Andre Gregori; 15.06.2015
comment
Я просто хотел бы указать на нюанс Скотт Майлз, заключающийся в том, что поле readOnly в объявлении свойства не исключительно управлять поведением свойства в отношении элементов вне локальной модели DOM, но также и элементов внутри локальной модели DOM. IOW, если я устанавливаю свойство как доступное только для чтения, оно доступно только для детей, а также для предков. - person Andre Gregori; 15.06.2015
comment
Просто для ясности: это не означает, что свойства, доступные только для чтения, никогда не могут быть изменены; свойство только для чтения можно изменить с помощью специального метода установки, но, насколько я понимаю, это не с помощью API привязки данных. - person Andre Gregori; 15.06.2015
comment
Вы, сэр, заслуживаете медаль - person FrancescoC; 25.08.2016

Вам нужно изменить это:

<input type="text" value="{{value}}">

в

<input type="text" value="{{value::input}}">

попробуйте здесь. Это говорит о том, что полимер должен слушать события ввода. Объяснение здесь (не очень однозначно ИМО).

person Andrey    schedule 14.06.2015
comment
Вы правы, это где-то похоронено в документах; Я отредактировал приведенный выше ответ со ссылкой на документы (ждет рецензирования), но я также вставлю его сюда, чтобы любой мог легко его найти: polymer-project.org/1.0/docs/devguide/ - person Andre Gregori; 15.06.2015

Как отметили Андрей и Скотт Майлз, оба эти решения будут работать для получения двусторонней привязки с собственным полем ввода HTML.

<input type="text" value="{{value::input}}">

<input type="text" value="{{value::change}}">

С важным отличием:

::change будет срабатывать только тогда, когда текстовое поле теряет фокус или нажата клавиша ввода.

::input будет срабатывать при каждом нажатии клавиши.

person Steven Spungin    schedule 16.12.2017