"Web Components" and "Custom elements" are often mixed up, and web searches for the title of this question don't yet produce much clarity. Let's fix that.
JavaScript – Difference Between Web Components and Custom Elements
componentdomjavascriptweb-development
Related Solutions
The code you have is pretty good. The thing that seems a bit off-putting is the initialization code is not part of the object itself. That is, you can instantiate an object, but if you forget to call its wiring class, it's useless.
Consider a Notification Center (aka Event Bus) defined something like this:
class NotificationCenter(){
constructor(){
this.dictionary = {}
}
register(message, callback){
if not this.dictionary.contains(message){
this.dictionary[message] = []
}
this.dictionary[message].append(callback)
}
notify(message, payload){
if this.dictionary.contains(message){
for each callback in this.dictionary[message]{
callback(payload)
}
}
}
}
This is a DIY multi-dispatch event handler. You would then be able to do your own wiring by simply requiring a NotificationCenter as a constructor argument. Sending messages into it and waiting for it to pass you payloads is the only contact you have with the system, so it's very SOLID.
class Toolbar{
constructor(notificationCenter){
this.NC = notificationCenter
this.NC.register('request-toggle-contact-form-modal', (payload) => {
this.toggleContactForm(payload)
}
}
toolbarButtonClicked(e){
this.NC.notify('toolbar-button-click-event', e)
}
}
Note: I used in-place string literals for keys to be consistent with the style used in the question and for simplicity. This is not advisable due to risk of typos. Instead, consider using an enumeration or string constants.
In the above code, the Toolbar is responsible for letting the NotificationCenter know what type of events it's interested in, and publishing all of its external interactions via the notify method. Any other class interested in the toolbar-button-click-event
would simply register for it in its constructor.
Interesting variations on this pattern include:
- Using multiple NCs to handle different parts of the system
- Having the Notify method spawn off a thread for each notification, rather than blocking serially
- Using a priority list rather than a regular list inside the NC to guarantee a partial ordering on which components get notified first
- Register returning an ID which can be used to Unregister later
- Skip the message argument and just dispatch based on the message's class/type
Interesting features include:
- Instrumenting the NC is as easy as registering loggers to print payloads
- Testing one or more components interacting is simply a matter of instantiating them, adding listeners for the expected results, and sending in messages
- Adding new components listening for old messages is trivial
- Adding new components sending messages to old ones is trivial
Interesting gotchas and possible remedies include:
- Events triggering other events can get confusing.
- Include a sender ID in the event to pinpoint the source of an unexpected event.
- Each component has no idea whether any given part of the system is up and running before it receives an event, so early messages may be dropped.
- This may be handled by the code creating the components sending a 'system ready' message , which of course interested components would need to register for.
- The event bus creates an implied interface between components, meaning there is no way for the compiler to be sure you've implemented everything you should.
- The standard arguments between static and dynamic apply here.
- This approach groups together components, not necessarily behavior. Tracing events through the system may require more work here than the OP's approach. For example, OP could have all of the saving-related listeners set up together and the deleting-related listeners set up together elsewhere.
- This can be mitigated with good event naming and documentation such as a flow chart. (Yes, the documentation is famously out of step with the code). You could also add pre- and post- catchall handler lists that get all messages and print out who sent what in which order.
You better express that information with a conceptual diagram than a component diagram. Meaning: draw two boxes and connect them directly with a arrowheaded line
Also see : Conceptual Diagram @ Wikipedia
What you are talking about is a very very high level view of a system. Component diagrams are not suitable for such high level views. Component diagrams are required to show all the used public functionalities of components. Being so, they help to understand the interactions between components in one look. So they need to be detailed.
Best Answer
Custom elements are a specification part of the Web Components standard, along with Shadow DOM, Templates and HTML imports.
From the spec:
History
The specification is now at v1. The previous version, v0, had been supported since Chrome 33, and had a different API, using
document.registerElement
- which is now deprecated.Usage
Custom elements can either be autonomous (creating a new element from scratch (that is, extending HTMLElement), or can customize an existing HTML element (such as HTMLButtonElement).
The second parameter to the
customElements.define()
call is the name of the class implementing the behavior of the element. See the examples in the spec for autonomous elements and for customized built-in elements.Custom elements are supported natively in some modern browsers, and can be polyfilled for older browsers going back to Safari 7+ and IE11. See also the v1 polyfill.
Templates and Shadow DOM
By using Templates and Shadow DOM in a custom element, you can make the element easier to handle and resusable.
Templates allow using HTML to declare the structure of custom elements:
Shadow DOM allows styles, ids and classes of the content to be scoped to itself. This prevents CSS bleeding or access to the custom element's internals from outside it.
Learn more
Google Developers articles: