【问题标题】:Using model binding with a tree object and recursive rendering in Razor pages?在 Razor 页面中使用带有树对象的模型绑定和递归渲染?
【发布时间】:2021-10-07 08:16:03
【问题描述】:

我有这门课:

public class SmartNode
{
    public string Key { get; set; }
    public object Value { get; set; }
    public JsonValueKind ValueKind { get; set; }
    public bool IsFinal { get; set; }
    public int Level { get; set; }
    public SmartNode ParentNode { get; set; }
    public List<SmartNode> SubNodes { get; set; } = new List<SmartNode>();
}

IsFinal 表示该对象表示一个简单的 JSON 节点(字符串、布尔值或数字..)如果 IsFinal 为 false,我会进行递归以获得“最终”属性:

这是剃须刀页面:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

@{
    if (Model.HeadNode != null)
    {
        using (Html.BeginForm())
        {
            await DrawNode(Model.HeadNode);

            async Task DrawNode(SmartNode node)
            {
                var margin = (node.Level * 20).ToString() + "px";
                if (!node.IsFinal)
                {
                    <h4 style="margin-left:@margin">@node.Key</h4>
                    foreach (var subnode in node.SubNodes)
                    {
                        await DrawNode(subnode);
                    }
                }
                else
                {
                    int i = 0;//temp
                    var id = node.Key + "_" + node.Level;
                    <div>
                        <label for="@id" style="margin-left: @margin">@node.Key</label>
                        @switch (node.ValueKind)
                        {
                            case System.Text.Json.JsonValueKind.Undefined:
                                break;
                            case System.Text.Json.JsonValueKind.Object:
                                break;
                            case System.Text.Json.JsonValueKind.Array:
                                break;
                            case System.Text.Json.JsonValueKind.String:
    
                                <input type="text" name="???.Value" value="@node.Value" id="@id" />
                                break;
                            case System.Text.Json.JsonValueKind.Number:
                                <input type="number" name="???.Value" value="@node.Value" id="@id" />

                                break;
                            case System.Text.Json.JsonValueKind.True:
                            case System.Text.Json.JsonValueKind.False:
                                <input type="checkbox" name="???.Value"
                                       checked="@(node.Value.ToString() == "True")"
                                       value="True" id="@id" />
                                <input name="???.Value" type="hidden" value="False">
                                break;
                            case System.Text.Json.JsonValueKind.Null:
                                <input type="text" name="???.Value" value="@node.Value" id="@id" />
                                break;
                            default:
                                break;
                        }
                    </div>
                }

            }

            <button type="submit">Save</button>
        }
    }
}

问题是如何分配剃刀的输入名称

我使用 .NET 5 Razor 页面。

【问题讨论】:

  • 你不能去掉IsFinal,而改用SubNodes.Count() == 0吗?
  • 是的,我可以,但我没有想到

标签: asp.net razor-pages model-binding


【解决方案1】:

不要直接在页面上执行此操作,而是创建一个执行渲染的组件,将节点传递给组件,并使组件包含每个子节点的自身实例。

恭喜你现在有了一个递归组件。

Edit1:组件(此处为 SmartTreeView.razor)看起来像这样:

<!-- Maybe some title per node, whatever -->
<h3>@Node.Key - @Node.Value</h3>

<!-- Render node data here, like -->
@if (Node.Value != null)
{
    <DataComponent data="@(Node.Value)" />
}

<!-- Then, recursion -->
@foreach (var node in Node.SubNodes)
{
    <span>@tab</span>
    <SmartTreeView Node="@(node)" />
}



@code {
    private const string tab = "\t";

    [Parameter]
    public SmartNode Node { get; set; }

}

然后页面将&lt;SmartTreeView Node="@(Model.HeadNode)" /&gt;放在任何地方。

【讨论】:

  • 你的意思是view-components
  • 是的,你可以像&lt;vc:custom-tree root="Model.HeadNode"&gt;&lt;/vc:custom-tree&gt;一样包含它
  • 我不应该发送当前节点,而不是整个树吗? ,例如:root:"node",但我想不可能将对象发送到 VC
  • 您的页面只有一个节点:根节点或在您的情况下为 HeadNode。递归只发生在组件中。
  • 您能举个例子吗?我试图将您的建议放在代码中,但它没有用,我最终得到的结果是没有视图组件的相同结果。我不明白“并使组件包含每个子节点的自身实例”
猜你喜欢
  • 2020-08-11
  • 2020-07-02
  • 2019-03-12
  • 1970-01-01
  • 2010-09-07
  • 2019-01-22
  • 2021-03-07
  • 2019-02-23
  • 1970-01-01
相关资源
最近更新 更多