Синтаксис C # MVC - Рекурсивный поиск в лямбда-шаблонах (EditorFor) - PullRequest
0 голосов
/ 15 марта 2012

У меня есть рекурсивная модель.

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

У меня есть EditorTemplate для класса Mapping. Нормальный рендеринг через EditorFor (m => m.ChildMappings) работает нормально.

Основываясь на параметре массива (2,3), я бы хотел найти конкретный узел-потомок. (Например, Mapping.ChildMappings [2] .ChildMappings [3]).

Я попытался вызвать локальный метод в лямбде, который дал мне ошибку об индексаторах и обо всех вещах, которые я не могу сделать в шаблоне.

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

Итак, есть ли способ обернуть то, что я работаю в пакете, больше похоже на мою неудачную первую попытку? Я также попробовал блок лямбда-кода, но мне было отказано, потому что он не может быть преобразован в дерево выражений.

1 Ответ

1 голос
/ 15 марта 2012

Что ж, возможно, это не тот путь, но он работает, когда вы создаете новый Html-помощник для объекта, который вы хотите выбрать:

@{  
    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; }
}
...