0

I'm trying to build a WebComponent where you can edit items in an array, with the Polymer javascript framework. Model to DOM bindings work OK, but DOM to Model doesn't - simplified example:

<polymer-element name="rep-test">
    <template>
        <template repeat="{{item in items}}">
            <input type="text" value="{{item}}" placeholder="changes don't work!">
        </template>
        <button on-click="{{add}}">Add</button>
        {{items}}
    </template><script>
        Polymer({
            ready: function() { this.items = [] },
            add: function() { this.items.push('') },
            itemsChanged: function() { console.log(this.items) } // debug
        })
    </script>
</polymer-element>
<rep-test></rep-test>

The items are correctly displayed in the input elements, but when I change the value inside an input, changes are not reflected to the model (items). The binding works only in one direction.

Is there any way to make the binding bidirectional, so that when a change occur in the DOM, it is copied in the model ?

I've seen this todo demo which achieves this effect, but it does so with custom events associated with items changes. This obviously works but I'm looking for a more declarative way of doing this with bindings.

Antoine
  • 13,494
  • 6
  • 40
  • 52
  • 1
    Changes in `items` are changes in the `array` itself (items added / removed / reordered), the changes in underlying items are neither propagated nor treated as array changes anyway. – Aleksei Matiushkin Jan 14 '15 at 12:53
  • @mudasobwa: OK, but since angularJS propagates items it must be possible ? Or is it a design choice from Polymer ? – Antoine Jan 14 '15 at 12:57
  • 1
    A thought on this, here is one example that includes synchronising data: "By using an object with data properties, as in the edited version above, and only ever reading from and assigning to the data properties of that object rather than overwriting the object itself, changed values are shareable between instances." http://stackoverflow.com/questions/24867741/polymer-global-variables – Goce Ribeski Jan 23 '15 at 18:55

2 Answers2

1

Since changes in array’s elements are not reflected to itemsChanged, I would suggest you to listen on the input changes:

 <!--               ⇓⇓⇓⇓⇓⇓⇓⇓⇓ -->
 <input type="text" on-change="{{ itemChanged }}" 
        value="{{item}}" placeholder="changes don't work!">

 [...]

 <!-- inside script -->
 itemChanged: function(e) {
   console.log(e.path[0].value)
 }

Below is the link to the working example: http://plnkr.co/edit/sZYHeMuAVB0G1muHhFNK?p=preview

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • Thanks, I'm aware of this method, as I mentioned in my question I came across this in the todo demo code, but I was wondering if there was a way to avoid events. So I'll wait a bit for other inputs, before accepting this. – Antoine Jan 14 '15 at 13:43
  • 1
    You actually should not accept this because it does not answer your question. I posted this as an answer just for sake of formatting. – Aleksei Matiushkin Jan 14 '15 at 14:24
  • BTW, the example you’ve mentioned uses `on-td-input-commit="{{ addTodoAction }}"` handler. – Aleksei Matiushkin Jan 14 '15 at 14:25
0

Here is an example of bidirectional binding: as you change the values in the input fields model is updated:

Plunk

Follow data changes:
      <br>
      {{testData.employees[0].firstName}}
      <br>
      {{testData.employees[3].firstName}}
      <br><br>


      <template repeat="{{person in testData.employees}}">
        {{person.firstName}}
        <input type="text"  value="{{person.firstName}}">
        <br>
      </template>

I'll reference this post because it explains how this works better then I can:

"...if you change the data values, the new values are NOT available to all other instances - because the instance variables are just copies of the referenced strings. By using an object with data properties, as in the edited version above, and only ever reading from and assigning to the data properties of that object rather than overwriting the object itself, changed values are shareable between instances."

Community
  • 1
  • 1
Goce Ribeski
  • 1,352
  • 13
  • 30