ASP.Net - 布局中的循环/条件语句

时间:2011-09-21 14:55:50

标签: php asp.net vb.net listview loops

来自PHP,更具体地来自许多MVC框架,我已经习惯在布局中直接使用PHP中的基本foreachif构造。既然我正在学习ASP.NET,我会看到更多专有概念,如ListView来控制循环等......

所以举一个我想要做的例子......

<div id="container">
    <h1 class="header">Title</h1>

    <% For Each item In ItemsCollection %>
        <% If item.Name IsNot Nothing %>
            <h3>This is the layout for <%= item.Name %></h3>
        <% End If %>
        <p><%= item.Content %></p>
    <% Next %>

</div>

然后我不得不在Code Behind文件中处理很多...除了使ItemsCollection可用。

这被视为不良做法吗?我应该花时间学习ASP.NET的专有控件吗?这种方法有特定的局限性吗?

3 个答案:

答案 0 :(得分:2)

这可能是主观的,但是有很多关于为什么创建标准控件(如ListView)的文档。主要的好处是分离关注点,避免使用“意大利面条代码”,这正是您的样本。

我相信如果您要在.NET中开发,那么值得您花时间学习控件以及这些控件的背景知识。 .NET开发的许多功能,生产力,代码清晰度和易用性都取决于这些设计原则。与其他环境相比,它们是“正确”还是“正确”是值得商榷的。

以上所有......

简短版本是,如果您要使用WebForms模型在.NET中进行开发,那么您应该像.NET WebForms开发人员那样编写代码,如果没有其他原因,那么.NET WebForms开发人员可能会有一天需要维护你的代码。我们都接受过培训,期待某些事情,这样的事情会让我们在维护其他人的代码时感到疯狂。

修改

当然,如果你使用ASP.NET MVC,你将会进入你的舒适区,我的意见将不适用。

答案 1 :(得分:0)

如果您使用vanilla ASP.NET框架,那么您的示例不是最佳实践,您应该坚持使用服务器端控件模型。 ASP.NET旨在主要用作服务器端控件模型。您所描述的内容与传统ASP页面的匹配程度更高。

例如,Repeater控件可以完美匹配您的示例代码。

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.aspx

粗略的例子:

标记:

<asp:Repeater id="Repeater1" runat="server">
    <HeaderTemplate>
        <div id="container">
            <h1 class="header">Title</h1>
    </HeaderTemplate>
    <ItemTemplate>
        <h3>This is the layout for <%# DataBinder.Eval(Container.DataItem, "Name") %></h3>
        <p><%# DataBinder.Eval(Container.DataItem, "Content") %></p>
    </ItemTemplate>
    <FooterTemplate>
        </div>
    </FooterTemplate>
</asp:Repeater>

代码背后:

protected void Page_Load(Object sender, EventArgs e) 
{
    if (!Page.IsPostBack)
    {
         // create or retrieve some bindable datasource
         // ArrayList values = ....

         Repeater1.DataSource = values;
         Repeater1.DataBind();
    }
}

这是您的示例的匹配服务器端控件模型。 Repeater将按设计迭代您的项目集合并创建相同的最终结果。它基本上吐出标题模板,使用项模板迭代您的集合,然后吐出页脚模板。还有很多其他选项,这只是一个简单的例子。

答案 2 :(得分:0)

没有必要在ASP.NET中嵌入这样的代码和标记(除了一些例外;))。

相反,您可以拥有一个可以绑定到DataSource的ListView控件;例如:

 <h3>ListView Example</h3>

  <asp:ListView ID="VendorsListView"
    DataSourceID="VendorsDataSource"
    DataKeyNames="VendorID"
    OnItemDataBound="VendorsListView_ItemDataBound"
    runat="server">
    <ItemTemplate>
      <tr runat="server">
        <td>
          <asp:Label ID="VendorIDLabel" runat="server" Text='<%# Eval("VendorID") %>' />
        </td>
        <td>
          <asp:Label ID="AccountNumberLabel" runat="server" Text='<%# Eval("AccountNumber") %>' />
        </td>
        <td>
          <asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /></td>
        <td>
          <asp:CheckBox ID="PreferredCheckBox" runat="server" 
            Checked='<%# Eval("PreferredVendorStatus") %>' Enabled="False" />
        </td>
      </tr>
    </ItemTemplate>
  </asp:ListView>

  <!-- This example uses Microsoft SQL Server and connects   -->
  <!-- to the AdventureWorks sample database. Add a LINQ     -->
  <!-- to SQL class to the project to map to a table in      -->
  <!-- the database.                                         -->
  <asp:LinqDataSource ID="VendorsDataSource" runat="server" 
    ContextTypeName="AdventureWorksClassesDataContext" 
    Select="new (VendorID, AccountNumber, Name, PreferredVendorStatus)" 
    TableName="Vendors" Where="ActiveFlag == @ActiveFlag">
    <WhereParameters>
      <asp:Parameter DefaultValue="true" Name="ActiveFlag" Type="Boolean" />
    </WhereParameters>
  </asp:LinqDataSource>

Taken from here.

UPDATE :就条件语句而言,您可以处理ItemDataBound事件:

protected void VendorsListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
  if (e.Item.ItemType == ListViewItemType.DataItem)
  {
    ListViewDataItem dataItem = (ListViewDataItem)e.Item;
    string vendorID= (string)DataBinder.Eval(dataItem, "VendorID");
    // ...
  }
}