Bind a value between a parent and a child element

2019-02-10 15:39发布

问题:

Using Polymer, does anyone know how to bind a value between a parent and a child element?

Below is my attempt however it doesn't work.

Note: child-component needs to be created using JavaScript.

<dom-module id="host-component">
  <template>
      <div>{{sharedValue}}</div>
      <div id="childComponentContainer">
          <!-- CHILD-COMPONENT GETS CREATED HERE -->
      </div>
  </template>
  <script>
    Polymer({is:'host-component',
        properties:{
            sharedValue:{
                type: String,
                notify:true,
                observer: 'sharedValueChanged'
            }
        },
        attached: function(){
            var newElement = document.createElement('child-component');
            Polymer.dom(this.$.childComponentContainer).appendChild(newElement);
        },
        sharedValueChanged:function(d){
            console.log(d, ", said the child");
        }
    });
  </script>
</dom-module>

<dom-module id="child-component">
  <template>
      <input is="iron-input" bind-value="{{sharedValue}}" />
  </template>
  <script>
    Polymer({is:'child-component',
        properties:{
            sharedValue:{
                type: String,
                notify:true,
                reflectToAttribute:true,
            }
        },
    });
  </script>
</dom-module>

Thanks :)

回答1:

After re-reading Polymer's documentation (many times) I found a section about how Two-way data-binding events work where by on each change Polymer fires a DOM event. From this I came up with the work around below.

You'll notice this version also has two way binding so the host can change the child's value and the child can change the host's value!

<dom-module id="host-component">
  <template>
      <div>Host: <span>{{sharedValue}}</span></div>
      <div>Host: <span><input is="iron-input" bind-value="{{sharedValue}}" /></span></div>
      <div id="childComponentContainer">
          <!-- CHILD-COMPONENT GETS CREATED HERE -->
      </div>
  </template>
  <script>
    Polymer({is:'host-component',
        properties:{
            sharedValue:{
                type: String,
                notify:true,
                value: "Unchanged",
                observer: 'sharedValueChanged'
            }
        },
        attached: function(){
            this.$.childComponent = document.createElement('child-component');
            var host = this;

            //Listens to the child's sharedValue. When changed it will update host's sharedValue.
            this.$.childComponent.addEventListener("shared-value-changed", function(e){
                host.sharedValue = this.sharedValue;
            });
            Polymer.dom(this.$.childComponentContainer).appendChild(this.$.childComponent);
        },

        //Observes the hosts's sharedValue. When changed it will update child's sharedValue.
        sharedValueChanged: function(value){
            if (this.$.childComponent) {
                this.$.childComponent.sharedValue = value;
            }
        }
    });
  </script>
</dom-module>




<dom-module id="child-component">
  <template>
      <div>Child: <span>{{sharedValue}}</span></div>
      <div>Child: <span><input is="iron-input" bind-value="{{sharedValue}}" /></span></div>

  </template>
  <script>
  Polymer({is:'child-component',
        properties:{
            sharedValue:{
                type: String,
                notify:true,
                value:"Unchanged",
                reflectToAttribute:true,
            }
        }
    });
  </script>
</dom-module>