Skip to content

Latest commit

 

History

History
72 lines (56 loc) · 2.39 KB

10.shared_context.md

File metadata and controls

72 lines (56 loc) · 2.39 KB

Shared Context

When you create a bindinable element it register's itself on the binding engine as a binding context. There are times when you want to separate your code into smaller components, but you don't want each component to have its own context. Instead, you want to parent component to register a context, the others to use it.

Consider this element structure

<parent-element>
    <parent-header></parent-header>
    <parent-detail></parent-detail>
    <parent-footer></parent-footer>
</parent-element>

parent-header, parent-detail and parent-footer should share the binding context of parent-element.
To do this, the fist thing required is to override a property hasOwnContext in the bindable element to not assign a bindable context.

get hasOwnContext() {
    return false;
}

This will create a problem with the lifecycle events as it requires a binding context.
Two things need to happen.

  1. In the constructor of the context less component you need to get the context from the parent.
  2. You need to load the javascript of the context less component at the last possible moment to ensure the parent context has been set.
// parent-header constructor
constructor() {
    super();
    this._dataId = this.parentElement._dataId;
}
// parent-element's connectedCallback
async connectedCallback() {
    await super.connectedCallback();
    await import("./parent-header.js");
    await import("./parent-detail.js");
    await import("./parent-footer.js");
}

Why do this

In certain scenarios you may want to beind to the same data structure in order not to duplicate the binding data.
This would be the primary case on when you want to do this.

Pitfall

There is one pitfall you need to be careful of.
When sharing the context, when you bind to events for example:

<button click.call="myClick">Click me</button>

The function myClick must be on the object where the context is defined.

There is a workaround for this using a bit of javascript.
Let us say I have a button on parent-header.html and I want to bind to function called callback on parent-header.js. In the connectedCallback of parent-header you can do the following

this.registerEvent(this.querySelector("button"), "click", this.doSomething.bind(this));

Using registerEvent you don't need to worry about cleaning up the event as on disconnect that will be done on your behalf.