Closed
Description
Hi AspNetCore Team,
we are using Html WebComponents as base for our applications and interacting with them is extremly complex
from blazor, especially with CustomEvents
Here is a sample html web component:
customElements.define('webcomp-event', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
this._clickCount = 0;
// Attach a shadow root to <fancy-tabs>.
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<label>
<input type="checkbox" id="my-checkbox"></input>
Change to Raise event
</label>
`;
// Internal event listener
shadowRoot.querySelector('#my-checkbox').addEventListener('click', (e) => {
this._clickCount++;
this.customCheckEvent = new CustomEvent("customcheck", {
detail: {
clickCount: this._clickCount,
isChecked: e.target.checked
},
bubbles: true,
composed: true,
cancelable: false,
});
this.dispatchEvent(this.customCheckEvent);
console.log(`input.clickEvent ${e.target.checked}`);
});
}
});
I would like to have something like that for handling custom Events in Blazor:
<webcomp-event @oncustom:customcheck="CustomHandlerAsync"></webcomp-event>
@code {
// Framework class:
public class CustomEventHandlerArgs : EventArgs
{
public dynamic Detail { get; set; }
}
public async Task CustomHandlerAsync(CustomEventHandlerArgs args)
{
await JSRuntime.InvokeVoidAsync("alert", $"FromBlazor ClickCount: {args.Detail.clickCount} IsChecked: {args.Detail.isChecked}");
}
}
But what I currently need to do is the following:
Index.razor:
<webcomp-event @ref="_eventRef"></webcomp-event>
@code {
private DotNetObjectReference<Index> _thisRef;
private ElementReference _webcompSetProperty;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Events
_thisRef = DotNetObjectReference.Create<Index>(this);
await JSRuntime.InvokeVoidAsync("registerBlazorCustomHandler", _eventRef, "customcheck", _thisRef, "HandleCounterClickAsync");
}
[JSInvokable("HandleCounterClickAsync")]
public async Task HandleCounterClickAsync(bool isChecked, int clickCount)
{
await JSRuntime.InvokeVoidAsync("alert", $"FromBlazor ClickCount: {clickCount} IsChecked: {isChecked}");
}
public void Dispose()
{
_thisRef?.Dispose();
}
}
Javascript:
function registerBlazorCustomHandler(component, eventName, callbackClass, callBackMethodName) {
component.addEventListener(eventName, (e) => {
console.log(`blazorjshandler clickcount: + ${e.detail.clickCount}`);
callbackClass.invokeMethodAsync(callBackMethodName, e.detail.isChecked, e.detail.clickCount);
});
}
Could this be improved:
I build a repository with differnet html web component issues, there are also other issues in there :
https://github.com/MichaelPeter/BlazorWebComponentTestApp
importaint are
https://github.com/MichaelPeter/BlazorWebComponentTestApp/blob/master/Pages/Index.razor
and
https://github.com/MichaelPeter/BlazorWebComponentTestApp/blob/master/wwwroot/scripts/TestWebComponents.js