You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从JS订阅Blazor组件事件?Blazor WASM嵌入旧Razor页面场景

解决方案

下面是几种实现Blazor组件事件通知外部JS的实用方案,按解耦程度排序:

1. 直接调用全局JS函数(最简单场景)

如果你的JS函数是全局挂载的,直接在Blazor组件事件中通过IJSRuntime调用即可,无需复杂逻辑:

Blazor组件代码修改:

@inject IJSRuntime JsRuntime

<button @onclick="MyComponentChanged">触发事件</button>

@code {
    private async Task MyComponentChanged()
    {
        // 直接调用页面中的全局JS函数
        await JsRuntime.InvokeVoidAsync("thisShouldBeInvokedOnMyComponentChange");
    }
}

Razor页面的JS保持不变:

<MyBlazorComponent></MyBlazorComponent>
<script>
function thisShouldBeInvokedOnMyComponentChange() {
    console.log("Blazor组件事件触发了!");
}
</script>

2. 自定义DOM事件(推荐,解耦性好)

这种方式让Blazor组件和外部JS通过标准DOM事件通信,耦合度极低,适合复杂场景:

第一步:Blazor组件中派发自定义事件

先注入IJSRuntime,在事件触发时调用JS方法派发自定义事件:

@inject IJSRuntime JsRuntime

<button @onclick="MyComponentChanged">触发事件</button>

@code {
    private async Task MyComponentChanged()
    {
        // 可以传递自定义数据给JS
        var eventData = new { Message = "来自Blazor的事件数据" };
        await JsRuntime.InvokeVoidAsync("dispatchBlazorComponentEvent", eventData);
    }
}

第二步:Razor页面中添加JS事件监听

<MyBlazorComponent></MyBlazorComponent>
<script>
// 定义派发自定义事件的函数
function dispatchBlazorComponentEvent(data) {
    // 创建自定义事件,可携带数据
    const customEvent = new CustomEvent('MyComponentChanged', { 
        detail: data,
        bubbles: true // 允许事件冒泡,方便上层元素监听
    });
    // 选择Blazor组件的根元素派发事件(也可以用document)
    document.querySelector('myblazorcomponent').dispatchEvent(customEvent);
}

// 监听自定义事件
document.addEventListener('MyComponentChanged', function(e) {
    console.log("Blazor组件事件触发,数据:", e.detail);
    // 执行你的业务逻辑
});
</script>

3. 注册JS回调到Blazor组件(适合需要双向通信场景)

如果需要外部JS主动注册回调,或者传递复杂的回调逻辑,可以让Blazor保存JS回调的引用,触发事件时调用:

Blazor组件代码:

@inject IJSRuntime JsRuntime
@implements IAsyncDisposable

<button @onclick="MyComponentChanged">触发事件</button>

@code {
    private DotNetObjectReference<MyBlazorComponent>? _selfReference;
    private Action<object>? _jsCallback;

    protected override async Task OnInitializedAsync()
    {
        _selfReference = DotNetObjectReference.Create(this);
        // 通知JS注册回调
        await JsRuntime.InvokeVoidAsync("registerBlazorComponentCallback", _selfReference);
    }

    private void MyComponentChanged()
    {
        var eventData = new { Id = 1, Content = "事件触发" };
        _jsCallback?.Invoke(eventData);
    }

    // 供JS调用的注册方法
    [JSInvokable]
    public void RegisterCallback(Action<object> callback)
    {
        _jsCallback = callback;
    }

    public async ValueTask DisposeAsync()
    {
        _selfReference?.Dispose();
        await JsRuntime.InvokeVoidAsync("unregisterBlazorComponentCallback");
    }
}

Razor页面的JS代码:

<MyBlazorComponent></MyBlazorComponent>
<script>
let blazorComponentReference = null;

function registerBlazorComponentCallback(componentRef) {
    blazorComponentReference = componentRef;
    // 注册回调函数到Blazor
    componentRef.invokeMethodAsync('RegisterCallback', (data) => {
        console.log("Blazor组件事件触发,回调收到数据:", data);
        // 执行你的业务逻辑
    });
}

function unregisterBlazorComponentCallback() {
    if (blazorComponentReference) {
        blazorComponentReference.dispose();
        blazorComponentReference = null;
    }
}
</script>

内容的提问来源于stack exchange,提问作者Ssss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:57:25