Skip to content

Instantly share code, notes, and snippets.

@larsgk
Last active October 10, 2016 11:10
Show Gist options
  • Save larsgk/28d4609f1a9eb1f8f2284962acfa9052 to your computer and use it in GitHub Desktop.
Save larsgk/28d4609f1a9eb1f8f2284962acfa9052 to your computer and use it in GitHub Desktop.
It's been tricky for me to figure out how to make singleton behavior in polymer (1.x) .. I'm probably getting old ;) .. anyway - here goes: A tick (1 sec interval) tock (1.5 sec interval) counter service.
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="app-data">
<script>
(function() {
console.log("This should only run once...");
var listeners = {
tickListeners: [],
tockListeners: []
}
var refcount = 0;
var g_data = {tick:0, tock:0};
setInterval(function(){
g_data.tick++;
_tick_changed();
}, 1000);
setInterval(function(){
g_data.tock++;
_tock_changed();
}, 1500);
var _tick_changed = function() {
//console.log("data tick changed", g_data.tick);
listeners.tickListeners.forEach( function(instance) {
instance.notifyPath('data.tick');
});
}
var _tock_changed = function() {
//console.log("data tock changed", g_data.tock);
listeners.tockListeners.forEach( function(instance) {
instance.notifyPath('data.tock');
});
}
// event handlers
document.addEventListener('event-app-data', function(evt) {
//console.log('evt received: ', evt);
if (evt && evt.detail && evt.detail.message) {
switch(evt.detail.message) {
case 'resettick':
g_data.tick = 0;
_tick_changed();
break;
case 'resettock':
g_data.tock = 0;
_tock_changed();
break;
}
}
});
Polymer({
is: 'app-data',
properties: {
data: {
type: Object,
value: g_data,
readonly: false
},
key: String
},
created: function() {
console.log("[app-data] created", this);
refcount++;
console.log("REFCOUNT:", refcount);
key = this.getAttribute('key');
if (!key) {
console.log(this);
throw('app-data element requires key');
}
switch(key) {
case 'tick':
listeners.tickListeners.push(this);
this.async(function(){this.notifyPath('data.tick')});
break;
case 'tock':
listeners.tockListeners.push(this);
this.async(function(){this.notifyPath('data.tock')});
break;
}
},
detached: function() {
console.log("[app-data] detached", this);
key = this.getAttribute('key');
var arr
switch(key) {
case 'tick':
arr = listeners.tickListeners;
break;
case 'tock':
arr = listeners.tockListeners;
break;
}
if(arr) {
var i = arr.indexOf(this);
if (i >= 0) {
instances.splice(i, 1);
}
}
}
});
}());
</script>
</dom-module>
@larsgk
Copy link
Author

larsgk commented Oct 9, 2016

Note: I know it's probably very hacky and most probably very non-polymer ... but seems to work and I'd like some feedback on how I can make it better. ALL other examples of "singletons" I have seen regarding polymer has relied on some form of data replication. This may work fine for small state observers - but not when you need e.g. a USB serial hardware manager that should be connected to as a service from potentially many different web component elements in different parts (visible and otherwise) of a rich single page app. Some controlling parts of the hardware, some listening on low frequency data and some relying on fast streaming sensor data coming through the same service component - that ALSO must be able to provide polymer data binding. Anyway, as I mentioned in the description: I might just be getting old :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment