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

时间:2012-03-15 19:14:36

标签: .net asp.net-mvc lambda mvc-editor-templates

我有一个递归模型。

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

我有一个Mapping类的EditorTemplate。通过EditorFor(m =&gt; m.ChildMappings)进行的正常渲染工作正常。

基于数组参数(2,3),我想寻找一个特定的后代节点。 (Mapping.ChildMappings [2] .ChildMappings [3]例如)。

我试过在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];
    }

目前我已经重新开启了至少可以促进硬编码数量的嵌套级别,如下所示:

    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;
    }

那么,有没有办法将我在包装中工作的东西包裹起来,就像我第一次尝试失败一样?我也尝试过一个lambda代码块,只是被拒绝,因为它无法转换为表达式树。

1 个答案:

答案 0 :(得分:1)

好吧,这可能不是预期的方式,但是当您为要选择的对象创建新的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)

在源文件中定义自定义数据容器,因为我找不到实现该接口的类。

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