首页 > 解决方案 > 为什么我的带有 ElementReference 和 IJSRuntime.InvokeAsync 的 blazor 组件在 for 循环中不起作用

问题描述

blazor(服务器)组件的标记中,我试图在循环内添加的每个元素上调用 javascript 函数。这有点难以解释......希望这个代码片段有帮助:

@page "/"
@inject IJSRuntime JS
@for(var i = 0; i < 3; i++)
{
    ElementReference div;
    <div @ref="div">this should get replaced....</div>
    JS.InvokeVoidAsync("Test", div, i); @* where Test is defined as: function Test(el, i) { el.innerHTML = i; }*@
}

如果我以错误的方式解决这个问题......什么是正确的方式?

对于更多上下文,这就是我真正想要做的:

@page "/"
@inject IJSRuntime JS
@foreach(var data in jsonItems)
{
    ElementReference div;
    <div @ref="div"></div>
    JS.InvokeVoidAsync("JsonView.renderJSON", data, div); @* https://github.com/pgrabovets/json-view *@
}
@code
{
    private readonly IEnumerable<string> jsonItems = new List<string> {"{}", "{}"};
}

如果有帮助,我已经创建了这个 blazor fiddle... https://blazorfiddle.com/s/428ov3ku

标签: blazorblazor-server-sideblazor-jsinterop

解决方案


在为元素分配引用之前,您不能使用 ElementReference 对象。您的组件尚未创建和渲染,因此没有可用的 ElementReference 对象。您只能在渲染组件后使用 ElementReference 对象。

你可以这样做:

@inject IJSRuntime JSRuntime

@foreach (var div in divs)
{
  
    <div @ref="div.ElementReference"></div>
  
}
@code
{
    private readonly IEnumerable<Div> divs = new List<Div> { new Div{JSON="{1}" },
                                                             new Div{JSON="{2}"},
                                                             new Div{JSON="{3}"}};

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {

        if (firstRender)
        {
            @foreach (var div in divs)
            {
            await JSRuntime.InvokeVoidAsync(
               "exampleJsFunctions.jsonRenderer", div.JSON, div.ElementReference);
            
            }
     
        }
    }

    public class Div
    {
        public ElementReference ElementReference { get; set; }
        public string JSON { get; set; } 

    }

 }

将脚本放在 _Host.cshtml 文件的底部...

 <script>
        window.exampleJsFunctions = {
            jsonRenderer: function (json, element) {
                element.innerText = json;
            }
        }
    </script>

推荐阅读