Consider the following Polymer custom element:
<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>
I believe I have declared the value
property as a two-way binding (notify: true
); yet when I click on the input and type in some text (say, "foo"
), it is not reflected in the model (i.e. a call to document.querySelector('test-element').value
returns the value I set in index.html, "test"
). Interestingly enough, the value
attribute of the input changes correctly, but the value property of my test-element does not. What am I missing?
I should also note that a call to document.querySelector('test-element').setAttribute('value', 'bar')
works properly.
First note that the notify
and reflectToAttribute
fields on the value
property tell it how to react to it's parent not about how to bind to a child.
IOW, notify: true
means to make value
two-way bindable from the outside, not from the inside. reflectToAttribute: true
tells Polymer to write value
to an attribute every time it changes (not good for performance).
When you do a binding like <x-element foo="{{value}}">
, it's x-element that decides if foo
is two-way bindable.
Native elements like input
do not have two-way binding support built in, instead use Polymer's event-observer syntax to two-way bind to an input. Like so
<input value="{{value::change}}">
.
This tells Polymer to update this.value
from input.value
whenever the input
fires a change
event.