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

如何无需按钮触发,从JS主动调用Blazor的DotNet方法

实现JavaScript主动调用Blazor DotNet方法(无按钮触发)

问题核心

原方案依赖按钮触发调用JS方法,但NavBar组件加载早于JSON解析完成,导致无法获取正确值。需改为JS解析满足条件后主动调用Blazor方法传递数据。


具体实现代码

1. NavBar.razor(修改组件,暴露可被JS调用的方法)

@inject IJSRuntime JSRuntime
@implements IAsyncDisposable

<a href="" @onclick=getName>手动获取(备用)</a>
<p>当前值:@Name</p>

@code {
    public string? Name { get; set; }
    private DotNetObjectReference<NavBar>? _componentRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 创建组件的DotNet引用,传递给JS保存
            _componentRef = DotNetObjectReference.Create(this);
            await JSRuntime.InvokeVoidAsync("registerNavBarRef", _componentRef);
        }
    }

    // 标记为可被JS调用的方法,方法名需与JS中调用的一致
    [JSInvokable("ReceiveName")]
    public void ReceiveName(string value)
    {
        Name = value;
        // 更新UI
        StateHasChanged();
    }

    // 原手动触发方法(保留作为备用)
    private async Task getName()
    {
        Name = await JSRuntime.InvokeAsync<string>("sendName");
        StateHasChanged();
    }

    // 释放引用,防止内存泄漏
    public async ValueTask DisposeAsync()
    {
        _componentRef?.Dispose();
        await JSRuntime.InvokeVoidAsync("unregisterNavBarRef");
    }
}

2. index.js(修改JS逻辑,满足条件时主动调用Blazor)

// 保存Blazor组件的DotNet引用
let navBarComponentRef = null;

// 注册组件引用
function registerNavBarRef(ref) {
    navBarComponentRef = ref;
}

// 注销组件引用
function unregisterNavBarRef() {
    if (navBarComponentRef) {
        navBarComponentRef.dispose();
        navBarComponentRef = null;
    }
}

function Create(fileName) {
    $.getJSON(fileName, function (data) {
        data.forEach((item) => {
            if (item.name === "something") {
                // 满足条件时,主动调用Blazor组件的方法
                if (navBarComponentRef) {
                    navBarComponentRef.invokeMethodAsync('ReceiveName', "Abc")
                        .catch(err => console.error("调用Blazor方法失败:", err));
                }
            }
        });
    });
}

// 保留原sendName方法(备用)
window.sendName = () => "Abc";

3. Index.razor(保持原有调用逻辑不变)

@inject IJSRuntime JSRuntime
@code {
    private string fileName = "your-target-file.json"; // 替换为实际JSON文件名

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("Create", fileName);
        }
    }
}

关键说明

  • 核心逻辑:通过DotNetObjectReference将Blazor组件实例传递给JS,JS持有引用后可主动调用组件上标记[JSInvokable]的方法
  • 加入了引用释放逻辑,避免内存泄漏
  • 原手动触发方法可保留作为备用场景使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:05:29