3 types of Event Communication
· Parent to child
· Child to Parent
· Unrelated components
Parent to child:
Note: Use @api decorator in child components
Passing message from parent to child:
ChildComp
<template>
Message will come here from Parent component :{message}
</template>
Js:
import { LightningElement,track,api } from 'lwc';
export default class ChildComp extends LightningElement {
@track message;
@api
changeMessage(strString)
{
this.message=strString.toUpperCase();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childComp">
<apiVersion>46.0</apiVersion>
<isExposed>false</isExposed>
</LightningComponentBundle>
Parent Component:
<template>
<lightning-card title="Parent to Child Demo">
<lightning-layout>
<lightning-layout-item flexibility="auto" padding="around-small">
<lightning-input label="Enter the message" onchange={handleChangeEvent}></lightning-input>
</lightning-layout-item>
<lightning-layout-item flexibility="auto" padding="around-small">
<c-child-comp></c-child-comp>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</template>
Js:
import { LightningElement } from 'lwc';
export default class ParentComp extends LightningElement {
handleChangeEvent(event)
{
this.template.querySelector('c-child-comp').changeMessage(event.target.value);
}
}
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="parentComp">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>
Child to Parent:
· Child component will create and Fire the event
· Parent component will handle the event
Handling the event in two ways:
· Declarative via html Markup
· JavaScript using add Event Listener
Declarative via html Markup
Creating Event in childComponent
const selectEvent=new CustomEvent('mycustomevent',{detail:name});
Dispatch/fire Event in child component:
this.dispatchEvent(selectEvent);
Handling the event in Parent side using html Markup
<c-child-component2 onmycustomevent={handleCustomEvent}></c-child-component2>
Here mycustomevent is eventName
childComponent2
<template>
<lightning-card title="Child Component">
<div class="slds-m-around_medium">
<lightning-input name="textVal" label="Enter Text" onchange={handleChange}></lightning-input>
</div>
</lightning-card>
</template>
Js
import { LightningElement } from 'lwc';
export default class ChildComponent2 extends LightningElement {
handleChange(event)
{
const name=event.target.value;
const selectEvent=new CustomEvent('mycustomevent',{detail:name});
this.dispatchEvent(selectEvent);
}
}
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childComponent2">
<apiVersion>46.0</apiVersion>
<isExposed>false</isExposed>
</LightningComponentBundle>
ParentComponent2:
<template>
<div class="slds-m-around_medium">
Value from Child: {msg}
<c-child-component2 onmycustomevent={handleCustomEvent}></c-child-component2>
</div>
</template>
import { LightningElement,track } from 'lwc';
export default class ParentComponent2 extends LightningElement {
@track msg;
handleCustomEvent(event)
{
this.msg=event.detail;
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="parentComponent2">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Push Parent component to LightningPage
Using AddEventListner Method:
childComponent3
<template>
<lightning-card title="Child Component">
<div class="slds-m-around_medium">
<lightning-input name="textVal" label="Enter Text" onchange={handleChange}></lightning-input>
</div>
</lightning-card>
</template>
Js:
import { LightningElement } from 'lwc';
export default class ChildComponent2 extends LightningElement {
handleChange(event)
{
const name=event.target.value;
const selectEvent=new CustomEvent('mycustomevent',{detail:name,bubbles:true});
this.dispatchEvent(selectEvent);
}
}
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="childComponent2">
<apiVersion>46.0</apiVersion>
<isExposed>false</isExposed>
</LightningComponentBundle>
ParentComponent3:
<template>
<div class="slds-m-around_medium">
Value from Child: {msg}
<c-child-component3></c-child-component2>
</div>
</template>
Js:
import { LightningElement,track } from 'lwc';
export default class ParentComponent2 extends LightningElement {
@track msg;
constructor()
{
super();
this.template.addEventListener('mycustomevent',this.handleCustomEvent.bind(this));
}
handleCustomEvent(event)
{
this.msg=event.detail;
}
}
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="parentComponent2">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Pub sub Model in Lightning Web Component:
Two components are not related to each other then we need to go for pub sub model. Its similar to Application Event in Aura Components.
· Need to use pubsub.js
· Publisher event takes 3 parameters: import these parameters pageRefrence,event Name,eventdetail from pubsub.js
· Subscriber component : Import registerListner,unregisterAllListner from pubsub.js file
PalettsPublisher:
<template>
<lightning-card title="Palette Publisher">
<lightning-layout>
<lightning-layout-item flexibility="auto" padding="around-small">
<lightning-combobox label="Color" value={color} options={colorCodeOptions} onchange={changeColor}></lightning-combobox>
<div class="slds-p-top_small">
<lightning-button label="change color" variant="brand" onclick={handleChangeColor}></lightning-button>
</div>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</template>
Js:
import { LightningElement,track,wire} from 'lwc';
import {fireEvent} from 'c/pubsub';
import {CurrentPageReference} from 'lightning/navigation';
export default class PalettePublisher extends LightningElement {
@track color;
@wire(CurrentPageReference) pageRef;
colorCodeOptions=[
{label:"Green",value:"green"},
{label:"Red",value:"red"},
{label:"Yellow",value:"yellow"},
{label:"Blue",value:"blue"}
];
changeColor(event)
{
this.color= event.target.value;
}
handleChangeColor()
{
console.log("color ->"+this.color);
fireEvent(this.pageRef,"changedColor",this.color);
}
}
Xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="palettePublisher">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Canvas:
<template>
<lightning-card title="Canvas Subscriber">
<lightning-layout-item flexibility="grow">
<div class="templateBodyClass" style={colorStyle}></div>
</lightning-layout-item>
</lightning-card>
</template>
Js:
import { LightningElement,track,wire } from 'lwc';
import {registerListener,unregisterAllListeners} from 'c/pubsub';
import {CurrentPageReference} from 'lightning/navigation';
export default class CanvasSubscriber extends LightningElement {
@track color;
@wire(CurrentPageReference) pageRef;
connectedCallback()
{
registerListener("changedColor",this.handleChangedColor,this);
}
disconnectedCallback()
{
unregisterAllListeners(this);
}
handleChangedColor(colorCode)
{
console.log("Color -->"+colorCode);
this.color=colorCode;
}
get colorStyle(){
return `background-color:${this.color}`;
}
}
css
.templateBodyClass{
height:80px;
}