收录日期:2019/06/20 13:43:12 时间:2010-06-22 20:32:39 标签:asp.net-mvc,coding-style,mvccontrib

I mean, now we have all this movement towards separating your html markup from your code as much as possible using modern template engines (in the old days programmers usually just kept concatenating strings in php, which was terrible.)

Then I look at a co-worker's code for generating an html table, and it looks like:

<% Html.Grid(Model).Columns(column => {
    column.For(x => Html.ActionLink("Edit", "Edit", new { id = x.Id })).Attributes(width => "30px").DoNotEncode();
    column.For(x => Html.ActionLink("Delete", "Delete", new { id = x.Id }, new { @class = "delete" })).Attributes(width => "95px").DoNotEncode();
    column.For(x => x.Id).Named("Code");
    column.For(x => x.Name).Named("Name").HeaderAttributes(align => "left");
    column.For(x => x.CPF).Named("CPF");
})
.Attributes(width => "100%", border => "0", cellpadding => "0", cellspacing => "0", @class => "data-table")
.Empty("No users found!")
.RowStart(row => string.Format("<tr class='row{0}'>", row.IsAlternate ? "-alternating" : ""))
.Render();
%>

He thinks it's awesome, I think it's quite ugly, so I'd like to know more people's opinion.

For a designer it's a step backwards in code readability, there are no two opinions here.

From a developer standpoint it will depend. Some like it others don't. Personally I like it and prefer it compared to the more standard foreach technique. Why?

You start with a simple <table> and a foreach. Then some user says that you need to handle alternating row styles. You start by adding ifs. Then another user says that you need to be able to order by given column. You handle this with yet another ifs. A third user asks you to handle paging => yet another ifs and foreach in your view. You end up with spaghetti.

Conclusion: use the right gun for the right target. For simple tables the conventional approach works nicely, but once you start doing more advanced stuff use helpers.

MVC Contrib Grid looks scary just because it has tons and tons of capability. Its a swiss army class HTML extension doing all things for all people. As others noted doing it by hand is even harder or clumsier. I remember back on the desktop, writing equally clumsy code to configure grid and spreadsheet controls to get the right effects.

However, iff your needs are more modest, just write your own. Phil Haack had a great article on a code based repeater. There are also some lighter Grid View Helpers out there that might assist you. These arent as powerful, but might be more suitable to certain jobs in your application.

I'll agree that it isn't very pretty, but if you start defining conventions for how a table should look, you could start to refactor to extension methods to clean this up a lot. Then it even DRYs up your table definitions. Here's an example (minus the actual extensionthods).

<% Html.Grid(Model).Columns(column => {
    InsertEdit(column).Width(30);
    InsertDelete(column).Width(95);
    column.For(x => x.Id).Named("Code");
    column.For(x => x.Name).Named("Name").LeftAlignHeader();
    column.For(x => x.CPF).Named("CPF");
})
.ApplyDefaultStyle()
.Class("data-table")
.Empty("No users found!")
.DefaultAlternatingStyle()
.Render();
%>

Its ugly on first glance, but I think its rather concise and takes care of a lot of logic. For example, a standard MVC output to do something close to this (without the markup)

    <table>
    <% dim index as integer = 0
      if model.count > 0 then %>
       <tr>
        <th>Edit</th>
        <th>Delete</th>
        <th>Code</th>
        <th align="left">Name</th>
        <th>CFP</th>
       for each item in model
         if index mod 2 = 0 then%>
           <tr>
         <%else%>
           <tr class ="alternate">
         <%end if%>
           <td><%= html.actionLink("Edit", "Edit", New With {.id = item.id})%></td>
           <td><%= html.actionLink("Delete", "Delete", New With {.id = item.id})%></td>
           <td><%: item.id%></td>
           <td><%: item.Name%></td>
           <td><%: item.CPF%></td>
         <% index += 1
            Next%>
    <%Else%>
        <tr><td>No Rows Found</td></tr>
    <%end if%>

</table>

And I am pretty sure I missed a few things in there as well. Going traditional, I have to keep track of a row count or some way to know if it is an alternating row or not, have a case when I have no records and generally a lot of <% %> tags to handle those code blocks.