Состав пользовательского интерфейса в ASP.NET MVC - PullRequest
5 голосов
/ 17 января 2009

Как бы вы поддержали внешние компонуемые детали в представлении ASP.NET MVC?

Что я имею в виду под этим? Подумайте либо «окно входа на каждой странице», либо «iGoogle». Это вещи, которые должны находиться в определенных местах, внешних по отношению к каждому контроллеру / представлению.

Один из подходов к этому - добавить компоненты в представление следующим образом:

<% foreach (var component in GetComponents()) {%>
    <%= Html.RenderPartial(component.ViewName, component.ViewData)%>
<%} %>

В приведенном выше примере я ищу хороший способ, чтобы имя и данные представления передавались контроллером каждого компонента, а не контроллером представления, на котором они отображаются. Любое совершенно другое решение, которое вы можете предложить, также будет интересно. Фильтры, веб-формы и т. Д.

Обновление: Я попытаюсь объяснить пример того, что я пытаюсь обернуть вокруг себя. Я выберу функциональность входа в систему.

В типичном приложении веб-форм это может быть пользовательский элемент управления, который извлекает соответствующие данные в событии загрузки жизненного цикла страницы и обновляет некоторые элементы управления пользовательского интерфейса. После щелчка страница будет отправлена ​​обратно, и мы можем использовать опубликованную информацию в событии щелчка в том же пользовательском элементе управления.

Насколько мне известно о стиле ASP.NET MVC, контроллер, который сначала принимает запрос , извлекает соответствующие данные и передает их представлению, которое, в свою очередь, передает это вместе с частичным представлением входа в систему. Представление входа в систему определило бы форму, действие сообщения которой направлено на действие входа контроллера входа в систему. опубликованная информация используется действием входа в систему, и мы можем выбрать передачу запроса первоначальному контроллеру по некоторой изящной схеме.

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

Ответы [ 4 ]

5 голосов
/ 18 января 2009

Есть два способа сделать это:

Первый: создайте BaseController, который всегда получает данные, необходимые для этих компонентов, установите ViewData ["loginbox"] = loginBoxData, а затем вы можете передать его таким образом.

<% foreach (var component in GetComponents()) {%>
        <%= Html.RenderPartial(component.ViewName, ViewData[component.Name])%>
<%} %>

Проблема этого метода в том, что вам нужно иметь логику, чтобы сказать, КОГДА все эти данные, необходимые для компонентов, будут выбраны, а когда нет.

TWO:

Существует библиотека DLL MVC Futures, которую вы можете загрузить с здесь .

Если вы ссылаетесь на это, и не забудьте добавить его пространство имен в ваш web.config, тогда вы сможете сказать: Html.RenderAction("blah") - этот метод совершает полное отключение, связываясь с контроллером, инициируя представление и возвращает HTML.

2 голосов
/ 18 января 2009

Вы можете использовать главную страницу и использовать заполнители содержимого для просмотра страниц содержимого и просмотра пользовательских элементов управления.

Шаблон проекта по умолчанию в бета-версии ASP.NET MVC Framework содержит заполнитель содержимого для страницы просмотра содержимого. В правом верхнем углу страницы также есть элемент управления просмотром пользователя для ссылки на вход / выход из системы.

Просмотр содержимого страницы

Предполагается, что страницы с содержимым представления будут использоваться с данными, полученными из просмотра, который вы просматриваете. То есть если вы переходите к действию Index в HomeController, сервер отобразит страницу просмотра Home/Index.aspx.

На главной странице вам нужна следующая строка:

<asp:ContentPlaceHolder ID="Holder1" runat="server" />

И на самой странице просмотра содержимого вы создаете для этого заполнителя следующее:

<asp:Content ID="Content1" ContentPlaceHolderID="Holder1" runat="server">
  <p>This text goes to "Holder1" content place holder and
     I can access the ViewData.</p>
  <p><%= ViewData["Message"] %>
</asp:Content>

Каждый asp:ContentPlaceHolder соответствует asp:Content представления через идентификатор. Так что если вы хотите несколько заполнителей, как это:

<asp:ContentPlaceHolder ID="Holder1" runat="server" />
<asp:ContentPlaceHolder ID="Holder2" runat="server" />

… вы можете обрабатывать их на странице просмотра содержимого следующим образом:

<asp:Content ID="Content1" ContentPlaceHolderID="Holder1" runat="server">
  <p>This text goes to "Holder1" content place holder</p>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Holder2" runat="server">
  <p>This text goes to "Holder2" content place holder</p>
</asp:Content>

Просмотр пользовательских элементов управления

View пользовательские элементы управления могут использоваться независимо от того, какой вид вы смотрите. Вот несколько примеров просмотра пользовательских элементов управления, взятых из сообщения в блоге Wekeroad о View User Controls Чтобы использовать пользовательский элемент управления view:

<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”)%>

Если у вас есть необходимость, вы также можете передавать ей данные и анонимные типы.

<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”,ViewData.Users, new {GroupID=2})%>
1 голос
/ 17 января 2009

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

Боюсь, что это не очень хороший ответ. я не понимаю этого: «... имеют имя и данные представления, предоставляемые контроллером каждого компонента, а не контроллером представления, на котором они отображаются».

0 голосов
/ 04 февраля 2012

Это старый вопрос, но вот мой взгляд на него с бритвой:

В приложениях в стиле CQRS вы можете выдвинуть ICommand к одной конечной точке службы, и служба выяснит, как ее маршрутизировать.

хороший пример этого: https://github.com/ncqrs/ncqrs/blob/master/Framework/src/Ncqrs/Commanding/ServiceModel/CommandService.cs

Что скажете - вместо того, чтобы пытаться выполнить команду, мы пытались выполнить запрос?

И вместо 1 мы передавали 1 или более как список IViewModelExecutor?

На главной странице у вас есть мастер ViewModel, в котором есть определение для каждой его подмодели, когда при загрузке страницы мы просим сервис получить все модели представлений, относящиеся к этому представлению:

service.Load(new List<IViewModelExecutor>{UserinfoViewModel, UserAccountViewModel });

служба загружает данные из readmodel и кэширует при необходимости. Модели подвидов передаются на подвиды с помощью Html.RenderPartial("subviewname", Model.SubViewModel)

Подвид знает, как визуализировать себя на основе модели.

Теперь - поскольку у нас есть составной пользовательский интерфейс с обновлениями ajax - допустим, мы хотим обновить часть страницы UserAccount. В контроллере у нас есть действие, которое отвечает за рендеринг ТОЛЬКО той части.

можно также запросить у service.Load(new List<IViewModelExecutor>{UserAccountViewModel })

и вернуть только ту часть модели представления, которая ему нужна - вероятно, кеширована. если параметры не меняются obv.

Теперь у нас есть составной пользовательский интерфейс, который может быть построен полностью или частично.

И, используя согласование содержимого, мы можем обслуживать фрагменты HTML, JSON или XML в зависимости от заголовков HTTP в запросе.

...