petshop里的CustomList是个什么东西?

简单明白地讲讲petshop4的多层应用是如何实现的:1)数据怎么取得

我知道有很多高手写了讲这个问题的文章,但我认我太菜,看不懂他们讲的那些,他们多数是从“架构和设计”角度讲,我不是技术总监,不需要知道这些,我需要知道的是如何用vs2005实现自己的多层应用,我希望能有高人从下面讲的角度入手讲解一下。不必讲多高深,也不必告诉我让我去看书,谢谢。

简单说,问题是:页面的内容是怎么从数据库中动态产生出来的?而且还是多层的?那些工厂类之类的东西,到底是多层的要素还是技术花招和迷雾?与这个“多层”有多大的关系?一个最简单的多层该是什么样的呢?希望高人能帮我拨开迷雾。

我思考和分析这问题是这样进行的:
在products.aspx文件中,用了母板页和内容页结构。母版页里有 contentplaceholder控件,这可以从工具箱的标准抽屉中拖到设计器上。在内容页(也就是products.aspx了)里,主要就是一个content,是用户定义的,这里又有用户定义的内容控件,叫customlist-productslist。形如:

<asp:Content ID="cntPage" ContentPlaceHolderID="cphPage" runat="Server" EnableViewState="false">  
    <PetShopControl:ProductsControl ID="ProductsControl1" runat="server" OnLoad="ProductsControl1_Load" />
</asp:Content>

这里是要用这个content去填充母板里的那个contentplaceholder所定的区域。
而内容本身又是从哪里来的呢?内容体是这段:

<PetShopControl:ProductsControl ID="ProductsControl1" runat="server" OnLoad="ProductsControl1_Load" />

这是一个从解决方案资源管理器中拖放出来的东西。具体是将control目录下的productscontrol拖过来就可以了。

好了,这样,我们的问题就集中到productscontrol的设计上了。

我找到controls/productscontrol.ascx,双击它,来研究它在设计器和源编辑器中的样子。

在设计器中,看到一个customlist-productslist,这个东西也该算控件吧,不过在工具箱中是没有的,算用户控件吧。试图找到一个可以拖放它的方法,未果。那么它是怎么跑到设计器上去的呢?

暂时放下它是怎么跑到设计器上的这个问题,先看看它到底是个什么东西。

在设计器上,看其属性,是petshop.web.customlist,这像是个用户定义的类或者说组件。右键点它,在快捷菜单上有几个可能有点击价值的选项:查看代码、查看组件设计器、编辑模板-项模板。
至于其属性,已经自动显示在属性管理窗口中了。

点‘查看代码’,结果就看到productslist.cs文件内容。和在解决方案资源管理器中双击这个文件一样效果。这里,定义了 productslist的部分内容:public partial class ProductsControl : System.Web.UI.UserControl {
注意这个partial,意思是还有其它定义内容在别的文件里。也就是说,一个类可以五马分尸并放到不同文件里了,据说这样对编程者有若干好处,不知道又没有坏处?这里主要定义了当页号改变时,内容要相应重新从数据库中得到,以及页面加载时,数据是怎么获得的。这两函数是pagechanged()和page_load()。

先不考虑研究pagechanged的问题,集中力量看看page_load的问题。

protected void Page_Load(object sender, EventArgs e) {
            this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
        }

而这里,引入了一个新玩艺:cachedependency,这是个什么东西?多层应用一定要用这个新式武器吗?原来,这是.net2.0引入的缓存机制。当页面装载时,先看看服务器缓存里有没有需要的东西,这里缓存的可能是装配好了的页面html。

暂时不管它,继续猜测。看这个事件的处理,看不出哪里去取数据了,估计这页面load事件后,紧接着就是pagechanged事件,所以取数据的活包给pagechanged事件处理函数了。

在pagechanged()里:
        protected void PageChanged(object sender, DataGridPageChangedEventArgs e) {
            //reset index
            productsList.CurrentPageIndex = e.NewPageIndex;

            //get category id
            string categoryKey = Request.QueryString["categoryId"];

            //bind data
            Product product = new Product();
            productsList.DataSource = product.GetProductsByCategory(categoryKey);
            productsList.DataBind();

        }

在bind data段里,是获取数据的实际工作。看来,这里又用了个新类:product。这个类负责把数据取得。于是我们继续追综product类。

namespace PetShop.BLL
{
    public class Product
    {
        public Product();

        public ProductInfo GetProduct(string productId);
        public IList<ProductInfo> GetProductsByCategory(string category);
        public IList<ProductInfo> GetProductsBySearch(string text);
    }
}

这个类玩了个花招,用了IList<>,这个IList就是IndexedList,意思是说可以根据索引访问的列表。
那个尖角括号是说,这里用了泛型,换个熟悉的词,就是模板吧。
public IList<ProductInfo> GetProductsByCategory(string category)看起来有点专家派头啊,用人民大众能听懂的词汇来说呢,就是说:有一个函数叫getproductsbycategory,它的参数是category,它返回的是productinfo作元素的的可索引的列表。既然是列表,就不是一般的数组,数组倒是可以根据索引来访问其元素,但数组不能随意扩展,而IList可以有随意个元素,而且,IList有现成的方法可以用。

好了,回到实际问题,在pagechanged时,发生
      productsList.DataSource = product.GetProductsByCategory(categoryKey);这个事情,这样,就把productslist里面的datasource填满了。

然而,我们还需要搞清,这里还有一个productslist类,而这是位什么神仙呢?换句话说,它有什么武功呢?右键点它,转到定义,可惜,对象定义被隐藏。这是什么秘籍?

看productscontrol.ascx文件,里面有:
<PetShopControl:CustomList ID="productsList" runat="server" EmptyText="No products found." OnPageIndexChanged="PageChanged" PageSize="4" RepeatColumns="2" CellPadding="16" CellSpacing="0" Width="500px">  

可见这里有ASP.net2的方言。翻译过来就是说:有一个customlist,给它起了个马甲叫productslist。。。晕。这是位customlist神仙。那么,我们去看customlist有什么武功吧。

而customlist就是个纯手工作品了。存在于app_code目录,文件名:CustomList.cs

 public class CustomList : DataList {
        //Static constants
        protected const string HTML1 = "<table cellpadding=0 cellspacing=0><tr><td colspan=2>";
        protected const string HTML2 = "</td></tr><tr><td class=paging align=left>";
        protected const string HTML3 = "</td><td align=right class=paging>";
      。。。。。。。。。

原来,customlist它爹是datalist。datalist它妈可是微软啊,略窥一下datalist的武功:

namespace System.Web.UI.WebControls
{
       public class DataList : BaseDataList, INamingContainer, IRepeatInfoUser
    {
        public const string CancelCommandName = "Cancel";
        public const string DeleteCommandName = "Delete";
        public const string EditCommandName = "Edit";
        public const string SelectCommandName = "Select";
        public const string UpdateCommandName = "Update";

。。。。。
凭这些武功,datalist在工具箱-数据抽屉 里有正式工作岗位。它是个可视化控件。

不过,customlist基于datalist添加了些花样,看上面的代码可以看到它用了些html元素当成员。

好了,回到本问题:数据怎么从数据库到内容页的?

基本上是:在products.aspx对应的products.cs文件里,定义了当页面改变时要从数据库里取数据并填充给索引化列表productslist的datasource。

这样就得到了数据。

那么,怎么体现多层呢?哪里有层呢?层和层间如何发生关系呢?另文再述,也十分希望高人对此问题进行回复。

 

关于如何从数据库中取出数据动态显示到页面,上面只是探讨了其骨架,在customlist-productslist.ascx文件中,那个productslist用户控件,内藏了一些asp代码。右键点它,有编辑项模板 菜单选项,进入后可看到人工录入的<%# Eval("Image") %> src属性。问题是,这个函数是怎么得到值的? 

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值