来自PHP,更具体地来自许多MVC框架,我已经习惯在布局中直接使用PHP中的基本foreach
和if
构造。既然我正在学习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的专有控件吗?这种方法有特定的局限性吗?
答案 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>
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");
// ...
}
}