Mathew
Mathew

Reputation: 670

Binding sub-properties with Google Polymer

Is it possible to bind sub-properties automatically with Google Polymer? Something like AngularJS.

Here is a small example:

This is the element that contains the property prop1 and updates it after 2sec:

<dom-module is="test-elem">

    <script>
        TestElem = Polymer({
            is: "test-elem",

            properties: {
                prop1: { type: String, value: "original value", notify: true }
            },

            factoryImpl: function() {
                var that = this;

                setTimeout(function(){
                    that.prop1 = "new value";
                }, 2000);
            }
        });
    </script>

</dom-module>

And this is the main page, which creates an element and show prop1 in the dom:

<template is="dom-bind" id="main-page">

    <span>{{test.prop1}}</span>

</template>

<script>
    var scope = document.getElementById('main-page');

    var t = new TestElem();

    scope.test = t;

</script>

Unfortunately, the page doesn't update with the new value. Is there a way to bind this automatically?

Here is a jsfiddle: http://jsfiddle.net/xkqt00a7/

Upvotes: 5

Views: 879

Answers (3)

jptknta
jptknta

Reputation: 817

Binding it as a sub property of the page scope doesn't work automatically because you need to manually call notifyPath('test.prop1', value) on the binding scope. One way to do that is to pass the binding scope to the TestElem constructor. Note that you don't need to worry about that if you bind to a parent element automatically. In that latter case the update is automatic.

The following works and shows two binding, and update, methods. One is automatic, the other requires a notifyPath call on the binding scope passed to the constructor.

  TestElem = Polymer({
    is: "test-elem",

    properties: {
      prop1: {
        type: String,
        value: "original value",
        notify: true
      }
    },

    ready: function() {
      var that = this;
      setTimeout(function () {
        that.prop1 = "new value (via ready)";
      }, 2000);
    },

    factoryImpl: function (app) {
      setTimeout(function () {
        app.notifyPath('test.prop1', 'new value (via app scope)');
      }, 2000);
    }
  });

.. then reference the element one of two ways:

  <test-elem prop1="{{prop1value}}">{{prop1value}}</test-elem>
  <div>{{test.prop1}}</div>
  <script>
    app.test = new TestElem(app);
  </script>

Where "app" is the main page's global binding scope (e.g. a as the a top level element in index.html, as is done in the polymer starter kit demo application).

After two seconds both properties update and the automatically updated html appears follows:

new value (via ready)
new value (via app scope)

Upvotes: 0

jojomojo
jojomojo

Reputation: 11

I can't explain why, but switching your example from setTimeout to this.async makes it work.

Upvotes: 1

Mathew
Mathew

Reputation: 670

The easiest way I found was to add an event handler:

t.addEventListener('prop1-changed', function(e){
        scope.notifyPath('test.prop1', e.currentTarget.prop1)
});

http://jsfiddle.net/83hjzoc3/

But it's not automatic like AngularJS.

Upvotes: 3

Related Questions