Flawyte Flawyte - 3 months ago 20
Javascript Question

Data binding on JavaScript HTMLElement property in Polymer

Making an SPA using Polymer, and I need my custom components to all use a common custom component which represents my backend API and is responsible of GET-ting/POST-ing data from/to the API. It also serves as a "cache" and holds the data to display. This way, all the components that have access to this single element will share the same data.

So what I want to do is this... :

<my-api
users="{{users}}"
products="{{products}}">
</my-api>


...but programmatically, as
<my-api>
is not declared in all of my components but once in the top one and then passed down through the hierachy by JavaScript:

Polymer({
is: 'my-component',
properties: {
api: {
observer: '_onApiChanged',
type: HTMLElement
},
products: {
type: Array
},
users: {
type: Array
}
},
_onApiChanged: function(newVal, oldVal) {
if (oldVal)
oldVal.removeEventListener('users-changed', this._onDataChanged);

// Listen for data changes
newVal.addEventListener('users-changed', this._onDataChanged);

// Forward API object to children
this.$.child1.api = newVal;
this.$.child2.api = newVal;
...
},
_onDataChanged: function() {
this.users = this.api.users; // DOESN'T WORK as 'this' === <my-api>
this.products = this.api.products; // Plus I'd have to repeat for every array
}
});


Does Polymer offers a built-in way to do this ? Can I create a double curly braces binding programmatically ?

Answer

I ended up using an other solution. Instead of manually passing the top <my-api> element down the hierarchy any element that needs access to this shared data declares its own <my-api>.

Then in the <my-api> element's declaration I made that all instances use the same arrays references. So whenever I update one they all get updated, and I don't have to pass anything down the HTML hierarchy, which makes things a LOT simpler.