Skip to content

Blazor Html WebComponents CustomEvents easier handling #27651

Closed
@MichaelPeter

Description

@MichaelPeter

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

Related:
#27070
#27654

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✔️ Resolution: DuplicateResolved as a duplicate of another issueStatus: Resolvedarea-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing one

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions