Blazor 参数化组件的实现

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

我开始使用 Blazor 开发 Web 应用程序。

我在一个问题上有点挣扎,这个问题似乎与我缺乏 blazor 做事方式的知识有关。

我有两个文件:

@page "/"
<PageTitle>Home</PageTitle>

<h1>Hello, word</h1>
@foreach(var component in WidgetsEditor)
{
    switch(component)
    {
        case MarkdownEditor me:
            <h1> Premier</h1>
            <MarkdownEditor />
            break;
        case PythonInterpreter pi:
            <PythonInterpreter/>
            
            
            break;
    }
    
}

<button @onclick="addMarkdownEditor">Add a Markdown Editor</button>
<button @onclick="addPythonEditor">Add a Python Editor</button>
@code{

    
    List<Widgets> WidgetsEditor = new()
        {
            new MarkdownEditor()
        };
    
    public void addMarkdownEditor()
    {
        WidgetsEditor.Add(new MarkdownEditor());
    }
    public void addPythonEditor()
    {
        WidgetsEditor.Add(new PythonInterpreter());
    }
}
and the PythonInterpreter component

@inherits Widgets
<script src="https://cdn.jsdelivr.net/pyodide/v0.25.1/full/pyodide.js"></script>
<input id="code" value="sum([1, 2, 3, 4, 5])" />
<button onclick="evaluatePython()">Run</button>
<br />
<br />
<div>Output:</div>
<textarea id="output" style="width: 100%;" rows="6" disabled></textarea>
<script>
  
  const output = document.getElementById("output");
  const code = document.getElementById("code");
  
  

  function addToOutput(s) {
    output.value += ">>>" + code.value + "\n" + s + "\n";
  }
 
  output.value = "Initializing...\n";
  // init Pyodide
  async function main() {
    let pyodide = await loadPyodide();
    output.value += "Ready!\n";
    return pyodide;
  }
  let pyodideReadyPromise = main();

  async function evaluatePython() {
    let pyodide = await pyodideReadyPromise;
    try {
      let output = pyodide.runPython(code.value);
      addToOutput(output);
    } catch (err) {
      addToOutput(err);
    }
  }
</script>
@code
{
    public int ident = 0;   

    [Parameter]
    public int Id{set;get;} = default!;
    
    
}

我想要的是参数化组件内的 html,并能够为其提供一个 ID。 我的应用程序应该允许用户通过单击按钮来添加块,因此我需要一个不断增加的 ID。

如果有人可以帮助我解决这个问题,我认为理解这一点将启发我对 Blazor 的整体看法。

非常感谢大家

我尝试使用 Blazor TemplatedComponent,我尝试使用 RenderFragment,但我未能真正理解如何使用它们。

blazor
1个回答
0
投票

您的想法并不遥远,但您正在将 Blazor 视为操作 DOM 对象的工具。 您应该将 DOM 视为 C# 数据的表达,即您当前概念化对象和数据之间关系的方式是落后的。 尝试一些更数据驱动的东西:

代码.cs

namespace WidgetDemo.Code
{
    public class WidgetData
    {
        public int ID { get; set; }
    }
    public class MarkDown : WidgetData
    {
        public string RawText { get; set; } = "";
    }
    public class PythonStuff : WidgetData
    {
        public string PythonCode { get; set; } = "";
    }
}

Home.razor

@page "/"
@using WidgetDemo.Code
@using WidgetDemo.Components.Editors
@rendermode InteractiveServer

<button @onclick=AddMarkup>+Markup</button>
<button @onclick=AddPython>+Python</button>

@foreach (var item in EditorData)
{
    switch (item)
    {
        case MarkDown MD:
            <MarkdownEditor MarkDown=MD />
            break;
        case PythonStuff PS:
            <PythonEditor PythonStuff=PS />
            break;
    }
    <button @onclick="()=>RemoveWidget(item)">X</button>
}
@code{

    List<WidgetData> EditorData = new();
    int IDcounter;

    async Task AddMarkup()
    {
        MarkDown newMark = new();
        newMark.ID = IDcounter++;
        EditorData.Add(newMark);
    }
    async Task AddPython(){
        PythonStuff newPython = new();
        newPython.ID = IDcounter++;
        EditorData.Add(newPython);
    }
    async Task RemoveWidget(WidgetData WD){
        EditorData.Remove(WD);
    }
}

MarkdownEditor.razor

@using WidgetDemo.Code

<h3>MarkdownEditor (WidgetID: @MarkDown.ID)</h3>
<div>Enter your Markdown text here:</div>
<textarea @bind=MarkDown.RawText />

@code {
    [Parameter]
    public MarkDown MarkDown {get; set;}
}

PythonEditor.razor

@using WidgetDemo.Code

<h3>PythonEditor (WidgetID: @PythonStuff.ID)</h3>
<div>Enter your Python code here:</div>
<textarea @bind=PythonStuff.PythonCode />

@code {
    [Parameter]
    public PythonStuff PythonStuff { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.