Can't seem to conditionally create a new table

2019-02-16 11:18发布

问题:

I want a loop to dynamically create a table up to 2 columns wide, and then increase the number of rows until there are no entries left in the list. Sounds easy, and I came up with this:

<table>
                    <tr>
                        @{ var i = 0; }
                        @foreach (var tm in Model.TeamMembers)
                        {
                            <td>@tm.FirstName @tm.LastName @tm.Role</td>

                            if(++i % 2 == 0)
                            {
                                </tr>
                                <tr>
                            }
                        }
                    </tr>
                </table>

But I get errors stating } expected both for the for loop and the if statement. If I change the tags to something else (like for instance) it works fine.

My guess is it's trying to validate the end of the row, sees it and decides the loop must be over? How can I make it NOT do that, or do I need to put the entire table inside the loop with a bunch of messy conditionals? :(

回答1:

Try like this:

@{ var i = 0; }
@foreach (var tm in Model.TeamMembers)
{
    <td>@tm.FirstName @tm.LastName @tm.Role</td>
    if(++i % 2 == 0)
    {
        <text></tr><tr></text>
    }
}

or:

@{ var i = 0; }
@foreach (var tm in Model.TeamMembers)
{
    <td>@tm.FirstName @tm.LastName @tm.Role</td>
    if(++i % 2 == 0)
    {
        @:</tr><tr>
    }
}


回答2:

Razor expects the HTML code following your C# code to be enclosed in a pair of html tags. Here you've got the ending tag first, and the starting tag later, that's why razor had trouble parsing the text.

Enclosing your html code block in solves this issue as pointed out by Darin.

You could read this quick guide by Phil Haacked http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx



回答3:

In Razor syntax you can use the @: To insert literal text.

@:This allows literal text & arbitrary html 

You can see how this is implemented in my solution posted below. It properly closes the table with the right number of table cells per row.

I needed a tabular radio button list with the ability to bind a selected value.

@{
   int iSelectedId = (int)ViewData["SelectedMember"];
   long iCols = 3;
   long iCount = Model.TeamMembers.Count();
   long iRemainder = iCount % iCols;                    
   decimal iDiv = iCount / repeatCols;                    
   var iRows = Math.Ceiling(iDiv);
}
<table>
  <tr>
    @for (int i = 0; i < iCount; i++)
    {
      var tm = Model.TeamMembers[i];
      <td><input type="radio" name="item" value="@(tm.Id)" @(tm.Id == iSelectedId) ? "checked=checked" : "") /> @(tm.FirstName) @(tm.LastName)) - @(tm.Role) </td> 

      if (i % iCols == iCols -1 && i < iCount - 1) 
      { 
        //The alternate syntax for adding arbitrary text/html @: 
        //was crucial in getting this to work correctly.
        @:</tr><tr>
      }
    }
    if (iRem > 0) 
    {
      <td colspan="@(iCols - iRem)">&nbsp;</td>
    }
  </tr>
</table>