Динамически определенные разделы содержимого в представлениях Razor - PullRequest
6 голосов
/ 14 июня 2011

Я пытаюсь реализовать мысль, которую я должен был разрешить динамически генерировать пользовательские разделы для моего сайта MVC 3 Razor.

Шаблон будет выглядеть примерно так

<div class="sidebar">
     @RenderSection("Sidebar", false)
</div>
<div class="content">
     @RenderSection("MainContent", false)
     @RenderBody()
</div>

Добавление представления со следующим кодом дает мне ожидаемый результат

DefineSection("MainContent", () =>
{
    this.Write("Main Content");
});
DefineSection("Sidebar", () =>
{
    this.Write("Test Content");
});

Выход:

<div class="sidebar">Test Content </div>
<div class="content">Main Content <p>Rendered body from view</p></div>

Глядя на это, казалось достаточно простым создать модель Dictionary<SectionName, Dictionary<ControlName, Model>>

var sectionControls = new Dictionary<string, Dictionary<string, dynamic>>();
        sectionControls.Add("MainContent", new Dictionary<string, dynamic>()
        { 
            {"_shoppingCart", cart}
        });
        sectionControls.Add("Sidebar", new Dictionary<string, dynamic>() 
        { 
            { "_headingImage", pageModel.HeadingImage },
            { "_sideNav", null }
        });
        pageModel.SectionControls = sectionControls;

Таким образом, приведенный выше код объявляет два раздела шаблона («MainContent» с корзиной и «Sidebar» с изображением и навигацией.

Так что теперь мое представление содержит код для рендеринга вывода, например

foreach(KeyValuePair<string,Dictionary<string,dynamic>> section in Model.SectionControls)
    {
        DefineSection(section.Key, () =>
        {
            foreach (KeyValuePair<string, dynamic> control in section.Value)
            {
                RenderPartialExtensions.RenderPartial(Html, control.Key, control.Value);
            }
        });
  }

Теперь, когда я запускаю этот код, оба раздела содержат одинаковое содержимое! Шаг по коду показывает путь загрузки следующим образом

Действие Возвращается, код выше выполняется в View, LayoutTemlpate начинает загружаться. когда RenderSection вызывается для этих двух разделов в шаблоне макета, представление снова запускается! Что кажется мне даже более странным, так это то, что конечный результат заключается в том, что «HeadingImage» и «SideNav» заканчиваются в разделах «Sidebar» и «MainContent». Раздел MainContent не содержит корзину, он содержит копию раздела боковой панели.

<div class="sidebar">
<h2><img alt=" " src="..."></h2>
..nav..
</div>
<div class="content">
<h2><img alt=" " src="..."></h2>
..nav..
<p>Rendered body from view</p>
</div>

Комментирование одного из двух определений разделов в Контроллере приводит к тому, что другой является единственным элементом (но он все еще дублируется!)

Кто-нибудь имел эту проблему раньше или знает, какие ограничения могут быть причиной такого поведения?

Редактировать: Отлично. Спасибо за связь, а также! Мне больно за новую версию Resharper с поддержкой бритвы.

1 Ответ

6 голосов
/ 14 июня 2011

Ваши лямбда-выражения имеют общую переменную section.
Когда вызывается любая лямбда, значение переменной current является последним разделом.

Вам необходимо объявить отдельную переменную внутри цикла .

foreach(KeyValuePair<string,Dictionary<string,dynamic>> dontUse in Model.SectionControls)
{
    var section = dontUse;

    DefineSection(section.Key, () =>
    {
        foreach (KeyValuePair<string, dynamic> control in section.Value)
        {
            RenderPartialExtensions.RenderPartial(Html, control.Key, control.Value);
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...