Я изо всех сил пытался получить частичный вид, работающий в Razor. Движок View не может понять смысл приведенного ниже кода, но он прост с использованием механизма ASPX View. Может кто-нибудь показать мне, как заставить это работать с Razor? Обратите внимание, что я просто пишу календарь, поэтому тег
появляется в конце каждой недели. Первым признаком проблемы является то, что код Razor не будет форматироваться в редакторе VS, и он жалуется, что в блоке while отсутствует закрывающая скобка. Я перепробовал все виды комбинаций, даже используя делегата. (Я думаю, что причиной проблемы может быть условный тег TR, потому что он выделен как ошибка, потому что он не закрыт.)
Бритва (не работает)
<table class="calendarGrid">
<tr class="calendarDayNames">
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
@{
var loopDate = gridStartDate;
}
@while (loopDate <= gridEndDate)
{
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
<tr class="calendarWeek">
}
<td class="calendarDay">
<span class="calendarDayNumber">@loopDate.Day</span>
@if (Model.AllCalendarDays.ContainsKey(loopDate.Date))
{
foreach (var ev in Model.AllCalendarDays[loopDate.Date])
{
<span class="calendarEvent">@ev.Venue</span>
}
}
</td>
@{
loopDate = loopDate.AddDays(1);
@if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
</tr>
}
}
}
ASPX (работает)
<table class="calendarGrid">
<tr class="calendarDayNames">
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
<%
var loopDate = gridStartDate;
while (loopDate <= gridEndDate)
{
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{
%>
<tr class="calendarWeek">
<%} %>
<td class="calendarDay">
<span class="calendarDayNumber">
<%: loopDate.Day %></span>
<% if (Model.AllCalendarDays.ContainsKey(loopDate.Date))
{
foreach (var ev in Model.AllCalendarDays[loopDate.Date])
{ %>
<span class="calendarEvent">
<%: ev.Venue %></span>
<% }
} %>
</td>
<% {
loopDate = loopDate.AddDays(1);
if (loopDate.DayOfWeek == DayOfWeek.Monday)
{ %>
</tr>
<% }
}
} %>
</table>
Рабочее решение в Razor, основанное на предложении модели представления @ jgauffin и уродливом необработанном html-решении @ dommer. В сочетании они почти эстетически приемлемы. :)
У модели теперь есть итератор
public IEnumerable<Tuple<DateTime, IList<CalendarEventDto>>> GridItems()
{
var loopDate = GridStartDate;
while (loopDate <= GridEndDate)
{
yield return new Tuple<DateTime, IList<CalendarEventDto>>(loopDate.Date, AllCalendarDays[loopDate.Date]);
loopDate = loopDate.AddDays(1);
}
}
Хорошо, Tuple ленив, но я, вероятно, создам другую модель для хранения более сложной информации о дате и событиях (IsPast / greyed и т. Д.).
Скучный вид
@foreach (var item in Model.GridItems())
{
if (item.Item1.DayOfWeek == DayOfWeek.Monday)
{
@Html.Raw("<tr class=\"calendarWeek\">");
}
@Html.Raw("<td class=\"calendarDay\">");
@Html.Raw(string.Format("<span class=\"calendarDayNumber\">{0}</span>", item.Item1.Day));
foreach (var ev in item.Item2)
{
@Html.Raw(string.Format("<span class=\"calendarEvent\">{0}</span>", Server.HtmlEncode(ev.Venue)));
}
@Html.Raw("</td>");
if (item.Item1.DayOfWeek == DayOfWeek.Sunday)
{
@Html.Raw("</tr>");
}
}
Обратите внимание, что когда я переформатирую источник View в VS, он получает вопиющую вкладку, с оператором if, имеющим около 10 вкладок слева от него, но нет предупреждений компиляции, и он делает то, что я хочу. Не приятно или просто. Я думаю, что разработчики Razor должны обеспечить некоторую поддержку явного разбиения и разбивки на код и разметку, чтобы, когда анализатор не мог проанализировать его однозначно, мы могли сказать ему, что мы собирались.
@ Решение Эндрю Медсестры
Эндрю «работает над созданием команды ASP.Net для создания анализатора Razor!». Его решение работает нормально, но по-прежнему выдает предупреждения компилятора и, очевидно, сбивает с толку Visual Studio, потому что код не может быть переформатирован без попадания в большую строку в несколько строк:
<tbody>
@foreach (var calDay in Model.GridItems())
{
if (calDay.DayOfWeek == DayOfWeek.Monday)
{
@:<tr class="calendarWeek">
}
<td class="calendarDay">
<span class="calendarDayNumber">@calDay.Day</span>
@foreach (var ev in calDay.CalendarEvents)
{
<span class="calendarEvent">@ev.Venue</span>
}
</td>
if (calDay.DayOfWeek == DayOfWeek.Sunday)
{
@:</tr>
}
}
</tbody>