如何在动态生成/操作的 HTML 上添加 @onclick 函数?

问题描述 投票:0回答:2

我有一些代码,它搜索文本字符串,并将某个子字符串的所有实例替换为包含 onclick 函数的元素。它看起来像这样:

private string ReplaceCitationLinks(string text, int documentIndex)
{
    for (var i = 1; i <= documentIndex; i++)
    {
        var html = "<span class='citation-link' @onclick='() => ShowCitation(" + i + ")'>(Dokument " + i + ")</span>";
        text = text.Replace("[doc" + i + "]", html);    
    }

    return text;
}

然后在 HTML 中调用:

@((MarkupString)ReplaceCitationLinks("Test string [doc1]. Test string [doc2]", item.Citations.Count))

所以在这种情况下,我只希望字符串的 [doc1] 和 [doc2] 部分可单击。问题是 @onclick 不起作用。我想我可能需要用其他方式来做这件事。有谁知道我将如何实现这一点?

c# blazor
2个回答
0
投票

这里的问题是 Blazor 不知道您的标记包含 Blazor 语法,如

@onclick

有多种方法可以解决这个问题,但我建议创建一个组件

TextRenderer
。在此组件中,您添加一个参数
Text
来接收文本和一个参数
OnSpanClick
。然后重写
BuildRenderTree
,解析文本以找出占位符的位置,然后按原样返回非占位符标记,并在
RenderTreeBuilder
上调用合适的方法来构建
span
语法,如

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
  // parse 'Text' to find placeholder positions

  // iterate over 'Text' in steps defined by the placeholder positions,
  // for example, start with 0, then jump to first placeholder at postion 10, then to second placeholder at position 56, etc.

  // in those steps above, decide whether the text range is normal markup, then return it as

  builder.AddContent(..., textRange);

  // otherwise build your clickable span like

  builder.OpenElement(..., "span");
  builder.AddAttribute(..., "onclick",
    EventCallback.Factory.Create(owner,
      async () => await OnSpanClick.InvokeAsync(documentNumber)));
  builder.AddContent(..., $"Dokument {documentNumber}");
  builder.CloseElement();
}

然后在需要的地方使用这个组件,例如

<TextRenderer Text="@..." OnSpanClicked="@..." />


0
投票

@onclick 是对 Action(或 Action 本身)的引用,它将在代码中执行。因此您不能将其作为字符串传递。

我最好的建议是将您的代码更改为如下所示:

@foreach(var i = 0; i < this.documents.Count(); i++) {
  var item = this.documents[i]
  <span class="citation-link" @onclick="() => @ShowCitation(i)">(@i) @documents[i]</span>
}

@code {
private List<string> documents = new (); // initialize anywhere on OnInitializedAsync

private void ShowCitation(int documentIndex){
  // process your code by finding the given documentIndex in the documents variable
}
}
© www.soinside.com 2019 - 2024. All rights reserved.