zoukankan      html  css  js  c++  java
  • ASP.NET 4.0 Ajax 实例DataView模板编程2

    ASP.NET4.0 Ajax实例--DataView模板编程2

    前一篇文章中向大家介绍了如何利用客户端代码实现DataView功能,下面我们来看看如何利用DataView实现主-从模式。

    • 什么是主-从模式

    想利用文字说明什么是主从模式,好像不太容易,不过通过下面的示意图说明,就比较方便,示意图如下:

    上图中,左边是用户列表,右边是用户的详细信息,点击左边列表中的某一个用户名,右边就显示该用户的详细信息。这时左边就是"",右边就是""

    • 实现方法

    实现主从模式(Master-Detail),可以有两种方法:

    1.        绑定方式实现(自动)。

    2.        代码方式实现(手动)。

    一. 绑定方式的实现

     利用绑定方式实现Master-Detail模式,代码量很少,开发速度快,缺点是灵活性差,因为很多情况下""数据是""数据经过运算后得到的,而不仅仅是简单的从数据库中将数据取出。因此绑定方式比较适合于直接数据显示(数据不需要经过加工就直接显示)实现过程如下:

    1.        数据库设计

    这里我们仍然使用Northwind数据库,我们关心的表如下图所示:

    2.        和前一个Blog中的实现过程一样,我们需要添加一个WCF服务,在WCF服务中添加我们自己定义的数据访问逻辑,然后在JS里调用。和前面文章不同的是,这里我们使用EntityFramework来实现数据访问操作(在现实的工程开发中,建议大家使用EntityFramework+ADO.NET,千万不要使用LinqToSql速度太慢了)。

    3.        添加EntityFramework实体类:

    首先,在网站里添加新项,选择ADO.NET Entity Data Model,如下图所示:

    然后,选择要映射的数据库,如下图所示:

    最后,选择要映射的表,如下图所示:

    生成的映射类视图,如下所示:

    4.        添加一个Ajax Enabled WCF,并修改其代码,如下所示:

     

    代码
    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Runtime.Serialization;

    using System.ServiceModel;

    using System.ServiceModel.Activation;

    using System.ServiceModel.Web;

    using System.Text;

    using NorthwindModel;



    [DataContract]

    public class CustomersInfo

    {

    [DataMember ]

    public string CustomerID

    {

    get;

    set;

    }

    [DataMember]

    public string CompanyName

    {

    get;

    set;

    }

    [DataMember]

    public string ContactName

    {

    get;

    set;

    }



    }

    [DataContract]

    public class OrdersInfo

    {

    [DataMember]

    public int OrderID

    {

    get;

    set;

    }

    [DataMember]

    public DateTime OrderDate

    {

    get;

    set;

    }

    [DataMember]

    public string ShipCountry

    {

    get;

    set;

    }

    }

    [ServiceContract(Namespace
    = "")]

    [AspNetCompatibilityRequirements(RequirementsMode
    = AspNetCompatibilityRequirementsMode.Allowed)]

    public class NorthwindService

    {

    [OperationContract]

    public List<CustomersInfo> GetAllCustomers()

    {

    List
    <CustomersInfo> result = null;

    using (NorthwindEntities context=new NorthwindEntities ())

    {

    result
    = context.Customers

    .Select(customer
    => new CustomersInfo()

    {

    CustomerID
    =customer .CustomerID ,

    CompanyName
    =customer.CompanyName,

    ContactName
    =customer .ContactName

    }).ToList ();



    }

    return result;

    }

    [OperationContract]

    public List<OrdersInfo> GetCustomerOrders(string customerID)

    {

    List
    <OrdersInfo> result = null;

    using (NorthwindEntities context = new NorthwindEntities())

    {

    result
    = context.Orders

    .Where(order
    => order.CustomerID == customerID)

    .Select(order
    => new OrdersInfo()

    {

    OrderID
    =order.OrderID,

    OrderDate
    =order.OrderDate.Value ,

    ShipCountry
    =order .ShipCountry

    }).ToList ();

    }

    return result;

    }

    }

    代码说明:

    1.         WCF中包括两个方法,GetAllCustomers获取全部用户信息,GetCustomerOrders获取指定用户的订单信息。

    2.         返回值中的CustomersInfo类和OrdersInfo类已经自动被标记成DataContract,所以可以直接用去WCF的数据协议。

    6.        设计页面,基本布局如下图所示:

    如图可见,左面是一个DataView,当选中左面某一个Customer之后,名字高亮显示,右面显示这个用户的详细信息。首先要添加一些必要的CSS,代码如下所示

     

    代码
    <style type="text/css">

    .sys-template

    {

    display
    : none;

    }

    .left

    {

    float
    : left;

    width
    : 198px;

    height
    : 193px;

    overflow-y
    : scroll;

    }

    .right

    {

    float
    : left;

    width
    : 331px;

    height
    : 190px;

    }

    .customerRow

    {

    width
    : 100%;

    padding-top
    : 2px;

    border-style
    : solid;

    border-color
    : Black;

    color
    : Blue;

    cursor
    :pointer;

    }

    .selectedItem

    {

    background-color
    : Gray;

    }

    </style>

    代码说明:

    1.         sys-template:所有的DataView都要应用该样式,目的是控制其可见性

    2.         customerRow: 显示用户名称行的样式

    3.         selectedItem:  当某一个用户被选中时,所选中行的样式

    7.        页面的HTML代码如下:

               

    代码
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnableCdn="True">

    <Services>

    <asp:ServiceReference Path="~/NorthwindService.svc" />

    </Services>

    <Scripts>

    <asp:ScriptReference Path="http://ajax.microsoft.com/ajax/beta/0911/MicrosoftAjax.js"

    Name
    ="MicrosoftAjax.js" />

    <asp:ScriptReference Path="http://ajax.microsoft.com/ajax/beta/0911/start.debug.js" />

    </Scripts>

    </asp:ScriptManager>

    <div style=" 540px">

    <div id="divLeft" class="left">

    <div id="dvUserList" class="sys-template">

    <div id="colUserName" class="customerRow" sys:command="Select">

    {binding CustomerID}

    </div>

    </div>

    </div>

    <div id="divRight" class="right">

    <div id="dvUserDetails" class ="sys-template">

    <div>

    <span>CustomerID:</span> <span>{binding CustomerID}</span>

    </div>

    <div>

    <span>CompanyName:</span> <span>{binding CompanyName}</span>

    </div>

    <div>

    <span>ContactName:</span> <span>{binding ContactName}</span>

    </div>

    </div>

    </div>

    </div>

    代码说明:

    1.         和前一个Blog相同,在页面中添加了一个ScriptManager,在ScriptManager中添加了WCF的引用,以及ASP.NET Ajax LibraryCDN引用,以便使用DataView控件。

    2.         ID"divLeft"DIV是左面的用户名列表区。

    3.         ID"divRight"DIV为右面的用户详细信息显示区。

    4.         "divLef"中包括一个ID"dvUserList"DIV,该DIV是我们使用的一个DataView,在该DataView中包括一个列,即:ID"colCustomerID"DIV,该列绑定到了CustomerID字段上。这里比较特殊的是,在"colCustomerID"中,我们添加了一个系统指令"sys:command="Select"",该标记的功能是:当鼠标点击这列的某一行时,该即被选定,同时该列的样式会改变成指定的样式(后面JS代码中体现),而且该DataViewselectedData属性将变成这一行所对就的记录。

    5.         "divRight"中包括一个ID"dvUserDetails"DIV,该DIV是用来显示用户详细信息的DataView。中间有三个列,分别绑定到CustomerIDCompanyName以及ContactName三个字段上。

       

    8.        在页面上添加JS控制代码,如下所示:

    代码
    <script>

    var masterView = null;

    var detailsView = null;

    window.onload
    = function () {

    Sys.require([Sys.components.dataView],
    function () {

    masterView
    = Sys.create.dataView($get("dvUserList"), {

    selectedItemClass:
    "selectedItem"

    });

    detailsView
    = Sys.create.dataView($get("dvUserDetails"));



    Sys.bind(detailsView,
    "data", masterView, "selectedData");



    NorthwindService.GetAllCustomers(
    function (result) {

    masterView.set_data(result);

    });

    });

    }

    </script>

    代码说明:

    1.         masterViewdetailsView分另为主从两DataView

    2.         在页面加载后(window.onload),通过Sys.require来加载相关的JS文件

    3.         创建masterView时,在Sys.create.dataView函数的第二个参数中,指定了masterView中的seletedItemClass属性,即:指定当masterView中的某一行被选中时所应用的样式。

    4.         利用Sys.Bind函数将两个DataView进行绑定,该函数中的第一个参数用来指定将数据绑定到谁,第二个参数指定将数据绑定到该对象的哪一个属性上。第三个参数是指定要绑定的数据的来源是哪个对象,第四个参数指定数据源对象中的哪个属性是用来获取数据的。

    5.         最后调用WCF Service获取所有用户数据,并利用masterViewset_data函数来绑定主DataView

    9.        运行后的效果如下图所示:

    在左面用户列表中选中一个用户,右面就会显示该用户的详细信息。

       

    二. 代码方式实现

    前面是通过绑定方式实现的主从模式。下面将功能扩展,我们还需要在点击用户的时候查看该用户的订单信息,订单信息是和Customers表关联的表,我们是无法利用简单绑定来取值的,因此,需要手动编码来控制主从模式。现在我们将页面的HTML代码做一下修改,再添加一个新的DataView,用来显示用户的订单信息。

    1.        新添加的DataViewHTML代码如下所示:

          2.        修改主DataView "dvUserList"HTML如下所示: 

     

    代码
    <div id="dvUserList" class="sys-template">

    <div id="colUserName" class="customerRow"

    sys:command
    ="Select"

    sys:CustomerID
    ={{CustomerID}}>

    {binding CustomerID}

    </div>

    </div>

    代码说明:

    这里为ID"colUseName"DIV添加了一个CustomerID属性,并将该属性绑定到CustomerID字段上。

    3.        修改JS代码,如下所示:

    代码
    <script>

    var masterView = null;

    var detailsView = null;

    var ordersView = null;

    window.onload
    = function () {

    Sys.require([Sys.components.dataView],
    function () {

    masterView
    = Sys.create.dataView($get("dvUserList"), {

    selectedItemClass:
    "selectedItem",

    onCommand: OnUserListCommand

    });



    detailsView
    = Sys.create.dataView($get("dvUserDetails"));



    ordersView
    = Sys.create.dataView($get("dvOrdersView"));



    Sys.bind(detailsView,
    "data", masterView, "selectedData");



    NorthwindService.GetAllCustomers(
    function (result) {

    masterView.set_data(result);

    });

    });

    }

    function OnUserListCommand(sender) {

    var command = sender.get_commandName();

    if (command == "Select") {

    var customerID = sender.get_commandSource().CustomerID;

    NorthwindService.GetCustomerOrders(customerID,
    function (result) {

    ordersView.set_data(result);

    });

    }

    }

    </script>

    代码说明:

    1.         代码中添加了一个ordersView对象,用来表示新添加的DataView

    2.         masterView的时候多添加了一个属性:onCommand,该属性是一个回调函数指针,该指针指向了"OnUserListCommand"函数,当鼠标对"dvUserList"中的任意一行执行操作时,OnUserListCommand函数都将被调用。

    3.         "dvUserList"中,我们只设置了select命令(sys:command="Select"),在OnUserListCommand函数中,通过调用sender.get_commandName()函数,可以知道我们对哪一个列进行了操作,因此,我们只要关心这个操作是不是"Select"即可。

    4.         通过sender.get_commandSource()可以获取我们所点击的那个DIV,之前我们已经在每一行的DIV中绑定了CustomerID字段,因此,可以通过sender.get_commandSource().CustomerID来获取被点击的那一行的CustomerID值。

    5.         通过调用WCF中的GetCustomerOrders函数,就可以获取指定用户的订单信息了。

    4.        运行效果如下所示:

    5.        完整的HTML代码如下所示:

    代码


    <DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head runat="server">

    <title></title>

    <script>

    var masterView = null;

    var detailsView = null;

    var ordersView = null;

    window.onload
    = function () {

    Sys.require([Sys.components.dataView],
    function () {

    masterView
    = Sys.create.dataView($get("dvUserList"), {

    selectedItemClass:
    "selectedItem",

    onCommand: OnUserListCommand

    });



    detailsView
    = Sys.create.dataView($get("dvUserDetails"));



    ordersView
    = Sys.create.dataView($get("dvOrdersView"));



    Sys.bind(detailsView,
    "data", masterView, "selectedData");



    NorthwindService.GetAllCustomers(
    function (result) {

    masterView.set_data(result);

    });

    });

    }

    function OnUserListCommand(sender, args) {

    var command = sender.get_commandName();

    if (command == "Select") {

    var customerID = sender.get_commandSource().CustomerID;

    NorthwindService.GetCustomerOrders(customerID,
    function (result) {

    ordersView.set_data(result);

    });

    }

    }

    </script>

    <style type="text/css">

    .sys-template

    {

    display
    : none;

    }

    .left

    {

    float
    : left;

    width
    : 198px;

    height
    : 193px;

    overflow-y
    : scroll;

    }

    .right

    {

    float
    : left;

    width
    : 331px;

    height
    : 190px;

    }

    .customerRow

    {

    width
    : 100px;

    padding-top
    : 2px;

    border-style
    : solid;

    border-color
    : Black;

    border-width
    : 1px;

    color
    : Blue;

    cursor
    : pointer;

    }

    .selectedItem

    {

    background-color
    : Gray;

    }

    </style>

    </head>

    <body>

    <form id="form1" runat="server">

    <div>

    <asp:ScriptManager ID="ScriptManager1" runat="server" EnableCdn="True">

    <Services>

    <asp:ServiceReference Path="~/NorthwindService.svc" />

    </Services>

    <Scripts>

    <asp:ScriptReference Path="http://ajax.microsoft.com/ajax/beta/0911/MicrosoftAjax.js"

    Name
    ="MicrosoftAjax.js" />

    <asp:ScriptReference Path="http://ajax.microsoft.com/ajax/beta/0911/start.debug.js" />

    </Scripts>

    </asp:ScriptManager>

    <div style=" 540px">

    <div id="divLeft" class="left">

    <div id="dvUserList" class="sys-template">

    <div id="colUserName" class="customerRow"

    sys:command
    ="Select"

    sys:CustomerID
    ={{CustomerID}}>

    {binding CustomerID}
    </div>

    </div>

    </div>

    <div id="divRight" class="right">

    <div id="dvUserDetails" class="sys-template">

    <div>

    <span>CustomerID:</span> <span>{binding CustomerID}</span>

    </div>

    <div>

    <span>CompanyName:</span> <span>{binding CompanyName}</span>

    </div>

    <div>

    <span>ContactName:</span> <span>{binding ContactName}</span>

    </div>

    </div>

    用户订单:

    <div id="dvOrdersView" class="sys-template" style="400px">

    <div style="border-1px;border-style:solid;border-color:Black;">

    <span>{binding OrderID}</span>--<span>{binding OrderDate}</span>--<span>{binding ShipCountry}</span>

    </div>

    </div>

    </div>

    </div>

    </div>

    </form>

    </body>

    </html>

       

    代码
    用户订单:

    <div id="dvOrdersView" class="sys-template" style="400px">

    <div style="border-1px;border-style:solid;border-color:Black;">

    <span>{binding OrderID}</span>--
    <span>{binding OrderDate}</span>--

    <span>{binding ShipCountry}</span>

    </div>

    </div>

     今天就聊到这儿,如何大家需要技术支援,请给我发Email:warensoft@foxmail.com

  • 相关阅读:
    CodeForces1152CNeko does Maths
    π的计算公式
    IFS变量对加双引号和不加双引号变量的区别对待
    各种距离
    ADO.NET Data Service 二 绑定数据类
    向客户端注入JavaScript代码
    Ajax ModelPopu and Progress 示例学习
    Sliverlight 入门教程七
    (牛人莫入)Jquery plugin 多文件上传
    自定义控件的验证使用
  • 原文地址:https://www.cnblogs.com/warensoft/p/1692658.html
Copyright © 2011-2022 走看看