Pass object to child component #6007
-
I'm looking to pass an entity's details in a js object to a child component. Currently, I'm having to stringify the object, then use an attribute converter to parse the JSON. Is there a more direct way to pass an object to a child without having to stringify and re-parse? And one that wouldn't be destructive to certain value types like a function? Example of what I have:
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Great question. I think there are a variety of approaches you can take. I'll toss a few out here and then maybe we can work together to determine the best approach for your scenario. BindingsIf both the parent component and the child component exist within a FAST templates, then you can actually use a binding to connect the two together. The approach would be to add a ref to the parent component and then a binding to that ref's property on the child component. Something like this: const template = html`
<parent-component ${ref('parentComponent')}>
<child-component :inputProperty=${x => x.parentComponent.outputProperty}></child-component>
</parent-component>
`; Known LookupAnother approach is to have the parent component store it's data in a specific location under some sort of id or key. Then the parent can set the key/id as an attribute on the child component and the child component could look that up and get the data. Something like this: <parent-component>
<child-component some-attribute="foo/1234"></child-component>
</parent-component> class ParentComponent extends FASTElement {
connectedCallback() {
super.connectedCallback();
cache.set("foo/1234", someObject);
}
}
class ChildComponent extends FASTElement {
connectedCallback() {
super.connectedCallback();
const someObject = cache.get("foo/1234");
}
} Dependency InjectionIf you are already using Community Context ProtocolIn W3C we're working on a protocol for components to request "context" from other components. In the vNext version of FAST, we'll have APIs that directly support this and have it integrated with our DI system. But for now, you can manually implement the protocol. It works by having the child component raise an event that the parent would handle to provide the object to the child. You can read all the details of the protocol here: https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md In your own code, you could implement it something like this: class ContextEvent extends Event {
public constructor(
public context,
public callback,
public multiple = false
) {
super("context-request", { bubbles: true, composed: true });
}
}
const MyContext = Object.freeze({ name: "my-context" }); // this functions as a unique key
class ParentComponent extends FASTElement {
constructor() {
this.addEventListener("context-request", e => {
if (e.context === MyContext) {
e.stopImmediatePropagation();
e.callback(myContextData);
}
});
}
}
class ChildComponent extends FASTElement {
myContextData = null;
connectedCallback() {
super.connectedCallback();
this.dispatchEvent(new ContextEvent(MyContext, value => this.myContextData = value));
}
} If you are curious about the context protocol, I've got a WIP PR for adding that to FAST here: #6053 There are probably more techniques than these, but these are the ones that come up most frequently. |
Beta Was this translation helpful? Give feedback.
Great question. I think there are a variety of approaches you can take. I'll toss a few out here and then maybe we can work together to determine the best approach for your scenario.
Bindings
If both the parent component and the child component exist within a FAST templates, then you can actually use a binding to connect the two together. The approach would be to add a ref to the parent component and then a binding to that ref's property on the child component. Something like this:
Known Lookup
Anothe…