#asp.net #razor-pages #model-binding
Вопрос:
У меня есть этот урок:
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>
}
}
}
Проблема в том, как я могу назначить входное имя из razor
Я использую страницы .NET 5 Razor.
Комментарии:
1. Не могли бы вы избавиться от
IsFinal
этого и просто использоватьSubNodes.Count() == 0
вместо этого?2. Да, я мог бы, но я об этом не подумал
Ответ №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; }
}
Затем страница просто помещается <SmartTreeView Node="@(Model.HeadNode)" />
куда угодно.
Комментарии:
1. Вы имеете в виду компоненты представления?
2. Да, вы бы включили его, как
<vc:custom-tree root="Model.HeadNode"></vc:custom-tree>
3. разве я не должен отправлять текущий узел, а не все дерево? , например:
root:"node"
, но я полагаю, что отправка объектов в VC невозможна4. Ваша страница имеет только один узел: корневой или, в вашем случае, головной. Рекурсия происходит только в компоненте.
5. Не могли бы вы привести пример? Я попытался изложить ваше предложение в коде, но оно не сработало, в итоге я получил тот же результат без компонента представления. Я не понял «и сделать так, чтобы компонент содержал экземпляры самого себя для каждого дочернего узла».