简体   繁体   English

C#MVC语法-在模板lambda中进行递归搜索(EditorFor)

[英]C# MVC Syntax - Recursive seeking in a template lambda (EditorFor)

I have a recursive model. 我有一个递归模型。

public class Mapping
{
    public string Value { get; set; }
    public List<Mapping> ChildMappings { get; set; }
}

I have an EditorTemplate for the Mapping class. 我有一个Mapping类的EditorTemplate。 Normal rendering via EditorFor( m => m.ChildMappings) works fine. 通过EditorFor(m => m.ChildMappings)正常渲染效果很好。

Based on an array parameter (2,3), I'd like to seek a specific descendant node. 基于一个数组参数(2,3),我想寻找一个特定的后代节点。 (Mapping.ChildMappings[2].ChildMappings[3] for example). (例如,Mapping.ChildMappings [2] .ChildMappings [3])。

I've tried calling a local method within the lambda, which gave me an error about indexers and all the things I can't do in a template. 我尝试在lambda中调用一个本地方法,这给了我关于索引器和模板中所有我不能做的事情的错误。

@Html.EditorFor(m => RecurseMappings(m.BodyMappings, indexes))

@functions{
    private Mapping RecurseMappings(List<Mapping> mappings, int[] indexes)
    {
        Mapping mapping = new Mapping();

        foreach (int index in indexes)
        {
            mapping = mappings[index];
            if (mapping.ChildMappings == null) { mapping.ChildMappings = new List<RequestMapping>(); }
            mappings = mappings[index].ChildMappings;
        }

        return mappings[mappings.Count - 1];
    }

For the moment I've fallen back on a switch to at least facilitate a hard coded number of nested levels, like this: 目前,我已经放弃使用开关,至少可以简化嵌套层的硬编码数量,如下所示:

    string[] tokens = Model.ChildIndex.Split(',');
    int[] indexes = Array.ConvertAll<string, int>(tokens, int.Parse);

   switch (indexes.GetLength(0))
    {
        case 1:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[last])
                break;
            }

        case 2:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[last])
                break;
            }
        case 3:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[last])
                break;
            }
        case 4:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[last])
                break;
            }
        case 5:
            {
                var last = Model.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[indexes[4]].ChildMappings.Count - 1;
@Html.EditorFor(m => m.BodyMappings[indexes[0]].ChildMappings[indexes[1]].ChildMappings[indexes[2]].ChildMappings[indexes[3]].ChildMappings[indexes[4]].ChildMappings[last])
                break;
            }
        default:
            break;
    }

So, Is there a way to wrap up what I have working in a package more like my failed first attempt? 因此,有没有办法像在我第一次失败的尝试中那样包装我在软件包中所做的工作? I've also tried a lambda code block, only to be denied because it can't be converted to an expression tree. 我还尝试了一个lambda代码块,但由于无法将其转换为表达式树而被拒绝了。

Well, probably this is not the intended way, but it works when you create a new Html-Helper for the object you want to pick: 好吧,这可能不是预期的方式,但是当您为要选择的对象创建新的Html-Helper时,它就可以使用:

@{  
    var dd =  new ViewDataDictionary<Mapping>(RecurseMappings(Model.BodyMappings, indexes));
    var dc = new MyDataContainer() { ViewData = dd };
    var help = new HtmlHelper<Mapping>(ViewContext, dc);
}

@help.EditorFor(m => m)

In a source file the definition of a custom data container, since I could not find a class that implements the interface. 在源文件中,自定义数据容器的定义,因为我找不到实现该接口的类。

public class MyDataContainer : IViewDataContainer
{
    public ViewDataDictionary ViewData { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM