Polymer 1.0 Global Variables
I've extended Etherealones' solution to work as a Behavior, and to extend Polymers "set" and "notifyPath" methods to trigger the updates automatically. This is as close as i could get to a true databinding across components/elements:
globals-behavior.html:
<script>var instances = [];var dataGlobal = {};var GlobalsBehaviour = { properties: { globals: { type: Object, notify: true, value: dataGlobal } }, ready: function() { var _setOrig = this.set; var _notifyPathOrig = this.notifyPath; this.set = function() { _setOrig.apply(this, arguments); if (arguments[0].split(".")[0] === "globals") { this.invokeInstances(_notifyPathOrig, arguments); } }; this.notifyPath = function(path, value) { _notifyPathOrig.apply(this, arguments); if (arguments[0].split(".")[0] === "globals") { this.invokeInstances(_notifyPathOrig, arguments); } }; }, invokeInstances: function(fn, args) { var i; for (i = 0; i < instances.length; i++) { instance = instances[i]; if (instance !== this) { fn.apply(instance, args); } } }, attached: function() { instances.push(this); }, detached: function() { var i; i = instances.indexOf(this); if (i >= 0) { instances.splice(i, 1); } }};</script>
And in all polymer elements that should have access to the globals variable:
<script> Polymer({ is: 'globals-enabled-element', behaviors: [GlobalsBehaviour] }); </script>
Examples:
- I have posted a full example as a Gist on Github
- Here's a snippet to see it in action:
I have implemented a pattern like iron-signals
uses for this purpose. So the basic principle is that you manually notify other instances when an update occurs.
Consider this:
<dom-module id="x-global"><script>(function() { var instances = []; var dataGlobal = {}; Polymer({ is: 'x-global', properties: { data: { type: Object, value: dataGlobal, }, }, attached: function() { instances.push(this); }, detached: function() { var i = instances.indexOf(this); if (i >= 0) { instances.splice(i, 1); } }, set_: function(path, value) { this.set(path, value); instances.forEach(function(instance) { if (instance !== this) { // if it is not this one instance.notifyPath(path, value); } }.bind(this)); }, notifyPath_: function(path, value) { instances.forEach(function(instance) { instance.notifyPath(path, value); }); }, fire_: function(name, d) { instances.forEach(function(instance) { instance.fire(name, d); }); }, });})();</script></dom-module>
You will simple call the version that have an underscore suffix like fire_
when you are firing an event. You can even create a Polymer Behavior of some sort with this pattern I guess.
Beware that preceding underscore properties are already used by Polymer so don't go ahead and convert these to _fire
.
P.S.:I didn't look around to solve how to reflect the notification of this.push(array, value);
as I don't need it. I don't know if it's possible this way. Should go find Polymer.Base.push
.