2015-06-14 4 views
11

Код

Рассмотрим следующий Polymer пользовательский элемент:Polymer 1,0: Двусторонний переплеты с входными элементами

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

ответ

27

Прежде всего обратите внимание на то, что поля notify и reflectToAttribute в собственности value рассказывают, как реагировать на его родителя, а не о том, как привязываться к ребенку.

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

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

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

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

+0

Спасибо. Теперь внутреннее/внешнее различие имеет смысл для меня. Я попросил изменить, добавив ссылку на документацию. –

+0

Я хотел бы указать на нюанс [Scott Miles] (http://stackoverflow.com/users/2192324/scott-miles) в том, что поле 'readOnly' в объявлении свойства не только определяет свойство поведение по отношению к элементам вне локальной DOM, а также элементы внутри локальной DOM. IOW, если я устанавливаю свойство как только для чтения, он доступен только для чтения как для детей, так и для предков. –

+0

Чтобы быть понятным, это не означает, что свойства, доступные только для чтения, никогда не изменяются; свойство read-only _is modifiable_ с помощью специального метода setter, но насколько я вижу, это не использование API привязки данных. –

12

Вы должны изменить это:

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

в

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

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

+1

Вы правы, где-то похоронили в документах; Я отредактировал ответ выше со ссылкой на документы (ожидая, что вас рецензируют), но я также добавлю его сюда, чтобы любой мог легко найти его: https://www.polymer-project.org/ 1,0/документы/devguide/данные binding.html # двухстороннего родной –

0

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

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

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

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

:: только огонь, когда текстовое поле теряет фокус или введите нажимается изменения.

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

Смежные вопросы