代码之家  ›  专栏  ›  技术社区  ›  Anthony

在ASP.NET MVC-HTML帮助器或部分视图中显示大量小值比较好

  •  1
  • Anthony  · 技术社区  · 16 年前

    我们有一个小型的ASP.NET MVC项目,它显示几十或数百行数据的报告。每一行由视图模型上的一个对象表示。

    当前我们显示的行如下:

    <table>
       <tr style="text-align:center">
            <th>Name</th>
            <th>Item count</th>
            <th>Stat 1</th>
            <th>Stat 2</th>
            <th>Etc</th>
       </tr>
    <%  var alternating = false;
        foreach(RowItem rowItem in Model.RowItems) 
        { %>
       <%= Html.BeginRow(alternating) %>
       <%= Html.ShowRow(rowItem) %>
       <% alternating = !alternating; %>
       <%= Html.EndRow() %>
       <% } %>
    </table>
    

    在哪里? BeginRow , EndRow ShowRow 是我编写的助手扩展方法。 展示区 是不是有点像

    public static string ShowRow(this HtmlHelper html, RowItem rowItem)
    {
       return "<tr><td>.... </tr>";
    }
    

    但我也可以代替 Html.ShowRow(rowItem) 用另一个局部视图,即 Html.RenderPartial("RowControl", rowItem);

    问题是,这两种方法的优点和缺点是什么?我能想到的是,局部视图更“可设计”——当amrkup复杂时更容易使用,并且由专门从事“设计”和“客户机开发”的团队成员使用,即HTML、CSS和javascript而不是C。HTML助手方法只是将包含所需HTML的字符串组合在一起,它吸引了一位老派的编码人员。

    哪一个(如果有的话)对数百个项目有显著的性能影响?它们中的任何一个都有可维护性影响吗?所有其他事物都是平等的,你会选择使用哪一个?

    我们现在使用的是ASP.NET MVC 1.0和Visual Studio 2008,但可能会在未来几个月内进行升级。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Dr. Wily's Apprentice    16 年前

    我不知道这有多有名(我只是在自己周围玩才知道),但实际上你可以使用匿名方法来定义页面内容的块,因此这是定义单独的局部视图的替代方法。当我只想重用一小部分HTML/服务器代码,或者不想在局部视图和调用视图之间定义复杂的模型/视图数据协定时,我发现这一点特别有用。

    下面是一些嵌入在视图中的代码的示例:

    // define example data
    IEnumerable<MyDataItem> data = new MyDataItem[] {
        new MyDataItem { Id = 1, Value = "ABC" },
        new MyDataItem { Id = 1, Value = "BCD" },
        new MyDataItem { Id = 1, Value = "CDE" },
        new MyDataItem { Id = 1, Value = "DEF" },
    };
    
    // an anonymous method to define reused HTML/server code
    Action<MyDataItem> displayData = delegate(MyDataItem item)
    {
        %><span class="my-data-class" title="This is my data!"><%= item.Value %></span><%   
    };
    %><div><%
    
    // use the displayData delegate to render a table       
    %><table><%
    foreach (MyDataItem item in data)
    {
        %><tr><td><% displayData(item); %></td></tr><%
    }   
    %></table><%
    
    // use the displayData delegate to render a set of divs
    foreach (MyDataItem item in data)
    {
        %><div><% displayData(item);%></div><%
    }   
    %></div><%
    

    上面的示例呈现以下HTML(为了清晰起见而格式化):

    <div>
      <table>
        <tr>
          <td>
            <span class="my-data-class" title="This is my data!">
            ABC</span>
          </td>
        </tr>
        <tr>
          <td>
            <span class="my-data-class" title="This is my data!">
            BCD</span>
          </td>
        </tr>
        <tr>
          <td>
            <span class="my-data-class" title="This is my data!">
            CDE</span>
          </td>
        </tr>
        <tr>
          <td>
            <span class="my-data-class" title="This is my data!">
            DEF</span>
          </td>
        </tr>
      </table>
      <div>
        <span class="my-data-class" title="This is my data!">ABC</span>
      </div>
      <div>
        <span class="my-data-class" title="This is my data!">BCD</span>
      </div>
      <div>
        <span class="my-data-class" title="This is my data!">CDE</span>
      </div>
      <div>
        <span class="my-data-class" title="This is my data!">DEF</span>
      </div>
    </div>
    
        2
  •  0
  •   Nick Larsen    16 年前

    在为MVC项目创建视图时,我通常尝试将所有相同的元素生成保持在相同的视图中。因此,对于您的情况,由于您正在创建一个表,我将确保所有表标记都在同一视图中创建。这有助于确保您正在创建格式良好的HTML,并使跟踪验证问题更加容易。

    我不太喜欢这里发生的事情,有几个原因。显示行扩展可能采用某种自定义 HtmlTableRow 对象作为其输入,它可能包含 HtmlTableCell 其中的每个对象都设置了样式属性。因为这些 HTML表格行 S是在您的控制器中创建的,它将您的演示与您的控制器紧密地结合在一起,这违反了MVC的关注点分离原则。

    下一步,如果更换 ShowRow 对于部分渲染,它将不会遵循我在第一段中建议的准则,即在不同视图中为同一个元素呈现标记。有时,您可以在不同的函数中呈现元素,但如果这样做,它们返回的对象应该实现可释放模式,并且只使用 using 声明。

    如果我要修改这个以便设计人员能够对设计有更多的控制权,我将在一个局部视图中呈现所有表,并为每个单元格提供一个描述性类名。我还将获取整个表并将其放在局部视图中,即使它是此页上唯一的内容。