Удаление логики из частичных представлений в ASP.NET MVC
-
12-09-2019 - |
Вопрос
Я знаю, что представления не должны содержать кода, но в проекте, над которым я работаю, в представлениях много логики.
На моей домашней странице есть
<% Html.RenderPartial("SearchResults"); %>
Теперь, в частичном представлении, у меня есть очень много такой логики;
<div id="RestaurantsList">
<%if (Model.restaurantsList.Count() > 0)
{
foreach (var item in Model.restaurantsList)
{ %>
<% Html.RenderPartial("SearchResult", item); %>
<%
} %>
<%
}
else
{
Html.RenderPartial("NoResults");
} %>
Теперь я мог бы заставить домашний контроллер возвращать другое представление на основе пустого списка, но на самом деле я этого не хочу, поскольку в индексном представлении есть несколько вещей, которые я хочу отображать, независимо от того, есть ли результаты или нет.
Единственное, о чем я могу здесь подумать, — это инкапсулировать это во вспомогательном методе, таком как Html.SearchResults.Но тогда мне понадобится помощник, который также будет вызывать renderPartial для каждого результата поиска.Это не похоже на чистое разделение задач.
Однако мне все равно пришлось бы иметь первый оператор if в частичном представлении.
Как бы вам лучше всего с этим справиться?
Решение
Моё личное мнение, что это нормально.Логика, которую вы использовали, полностью связана с тем, как должна отображаться модель.
Вам просто нужно знать и следить за тем, чтобы вы никогда не смешивали бизнес-логику, логику доступа к данным или что-то еще, что не связано строго с отображением модели.
Другие советы
Я согласен с ответом Правина Ангьяна.Единственное, что я мог бы сказать, чтобы расширить его ответ, — это добавить часть логики во ViewModel.
Например, в ViewModel вы можете скрыть
Model.restaurantsList.Count() > 0
за методом или свойством.
НАПРИМЕР.:
<%if (Model.HasResturant){...}%>
этот ответ не имеет ничего общего с вашим вопросом.
Однако я просто хочу сообщить вам, что вызов Html.RenderPartial() внутри цикла не эффективен.
ASP.NET MVC — цикл for внутри RenderPartial или снаружи RenderPartial
Было бы лучше изменить его на что-то вроде ниже.
<%if (Model.restaurantsList.Count() > 0)
{
// render the Restaurant item right away
foreach (var item in Model.restaurantsList) { %>
<div>
<%= Html.Encode(item.RestaurantName); %><br />
<%= Html.Encode(item.Address); %>
</div>
<% }
}
else
{
Html.RenderPartial("NoResults");
} %>
Правин Ангьян прав: это логика представления, и это нормально, что она там, где она есть.
Но это не меняет потребности в более аккуратных представлениях.
Просто хотел поделиться небольшим улучшением.
Если мы подключим крошечный метод HtmlHelper, мы сможем сократить представление примерно до этого:
<div id="RestaurantsList">
<% if (Model.HasRestaurants)
Html.RenderPartialForEach("SearchResult", Model.restaurantsList);
else
Html.RenderPartial("NoResults"); %>
</div>
Для кого-то это может выглядеть не читабельно и красиво, но мне вполне подходит.