Last active
October 10, 2016 11:10
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 :)