I have recently started using ASP.Net MVC 3 RC 2 and have attempted to migrate an existing website in MVC 2 across using the Razor syntax. In the MVC 2 application I am using the code base repeater that Phil Haack kindly provided in the following:
Phil Haack's Code Based Repeater
My question is around the syntax for Razor. I dont understand how the template in the following block can be rewritten in Razor and cannot find any documentation to help out (early days for documentation or my simplicity...):
<% Html.Repeater<ObjectToUse>(Model, "", "alt", (item, css) =>
{ %>
<tr class="<%= item.Enabled ? css : "disabled" %>">
<td><%= item.Name%></td>
<td><%= item.Description%></td>
<td><%= Html.RouteLink("Edit", item.ObjectToUseRouteValues("Edit"))%></td>
<td></td>
<td><%= Html.RouteLink("Select", item.ObjectToUseRouteValues())%></td>
</tr>
<% }); %>
The problem comes when applying the template between the braces (the tr's). I have attempted using the WebGrid control, however it doesnt provide the functionality I require for setting a "disabled" row (I think).
Actually, now that I think about it some more I don't think you can use Action
parameters like that in Razor. I recall running into this before.
Updated
With answer from Andrew Nurse:
"Unfortunately this is by design in the current parser, though I should note that we'd like to improve upon it. The issue is that markup is only valid at the start of a statement (which technically is where you've put it), but our C# "parser" is not intelligent enough to detect lambdas at the moment."
Though that might be out dated :)
@Html.Repeater(Model, "row", "row-alt",
@<tr class="@item.ClassType : "disabled"">
<td>@item.Name</td>
<td>@item.Description</td>
<td>@Html.RouteLink("Edit", item.ObjectToUseRouteValues("Edit"))</td>
<td></td>
<td>@Html.RouteLink("Select", item.ObjectToUseRouteValues())</td>
</tr>
)
public static IHtmlString Repeater<T>(this HtmlHelper html, IEnumerable<T> items,
string className, string classNameAlt, Func<T, HelperResult> render) {
if (items == null)
return new HtmlString("");
int i = 0;
StringBuilder sb = new StringBuilder();
foreach (var item in items) {
item.ClassType = item.Enabled ? (i++ % 2 == 0 ? className : classNameAlt) : "disabled";
sb.Append(render(item).ToHtmlString());
}
return new HtmlString(sb.ToString());
}
}
I wrote @helper
version.
@helper
do not use Generic method.
@helper ForEach(IEnumerable<int> items, Func<object, HelperResult> template){
foreach(var item in items){
Write(template(item));
}
}
<div>
<ul>
@ForEach(Enumerable.Range(1,5),
@<li>@item</li>
)
</ul>
</div>
hope this code.