I wanted to post an answer I gave recently to a web component question post training that we gave at Open Apereo. I asked Toben and he said it was ok if I posted the question / answer here because it's a common one. The issue related to state management methodologies when using primitive parts of "the platform". You could just use Redux, something my colleague Michael Potter recommends, but I'm more one for smaller methods (and 1 less dependency).
Hey Bryan, this is Toben, we met at Open Apereo. I was in your learn web components workshop. I have a question that I've been struggling with for the last day, and I figured you would probably know the answer off the top of your head.
I'm trying to pass an event up from one component to another. Let me describe quickly the construction of things:
I have this one chunk of code, a document tree view, that I use in 2-3 locations. I've been having to maintain the 2-3 code bases by hand, which makes me go "Perfect candidate for web component!" So I turned it into "doc-tree" and things were more or less ok.
A couple pieces of it weren't hooked up any more but I figured that was part of the re-implementation process. Inside of tree view I have a chunk of code that shows up in a couple of other places as well, a document source selector. So I figured it was another obvious candidate. So I made "doc-selector" and this is where I ran into my problem. When doc-selector document source changes, doc-tree needs to be notified that it happened and what it changed to, then doc-tree updates it's content to reflect the new source. And this is what I'm stuck on. How do I bubble up that event?
Hey Toben -
This is one of those expert level achievement unlocked, you are a web components master, type of problems. There's so many ways to solve it (state management of what you describe) that it can be a bit nuts. I find it best to pick a convention and stick to it, so the best place I can point you is to some parts of HAX which definitely stretched the levels of my comprehension of how to do this. Ok. so here's 2 design patterns in HAX, you pick which works best for you.
Body level attachment:
In this methodology, your element listens to events at the body of the document, yet says "when you hear this, bind it back to me". This is in the "this._verifyAction.bind(this)" portion of that code. It calls an event (and scope) to the element defined in, but yet it's listening on the body of the document. This is the easiest way by far of accomplishing this.
Event / Property Juggling:
So HAX data flow goes like this: there's a variable "store" / state manager (hax-store) which all changing of global properties needs to consistently flow through that .write function (which the store keeps itself as a global namespace so then all calls to write the store are from that). The store, effectively writes itself, which then triggers a call to fire a consistent event saying "a property has changed and here's its value". Then, everyone else that cares (like hax-body in this example) has said so listen (at the document.body level) for any call of a property changing, and then it subsequently updates itself.
This is how you can have elements anywhere in the tree yet subscribing to events in a uniform, global way no matter the structure. Listen at the top, telephone back down to the element in question to handle the processing.