我们大概了解了一些关于DinnerNow的基本项目结构,以及其中比较主要的两个解决方案文件。接下来我会继续以实际网上选餐流程来说明关于DinnerNow中的ASP.NET Ajax Extensions应用场景及其设计方案。

  首先请大家看一下这张图,它标明了在订餐这一业务流程中"查询餐馆"这一用例 DinnerNow所实际执行的方法顺序,因为下文中的一些主要的js方法调用也是以这张图中所标明的流程来顺序处理的.

  当然我们还要再次用VS2008打开上文中所说的两个解决方案文件:
    安装目录下\solution\DinnerNow - Web\DinnerNow - Web.sln
              \solution\DinnerNow - ServicePortfolio2\DinnerNow - ServicePortfolio2.sln

 不过这一回要说的重点内容集中在了DinnerNow - Web.sln下的DinnerNow.WebUX项目中.

  请看一下search.aspx页面的运行效果图:
  

上图中的数据请求在上一篇文章中已说过,就是:
service.FindRestaurant(PARAMETERS.map.PostalCode, 
PARAMETERS.map.MenuType, 
PARAMETERS.map.RestaurantCategory, 
PARAMETERS.map.DeadLine, 
onRestaurantSeachSuccess, //当操作请求成功后的回调方法
onRestaurantSeachFailed, null);
        
上面的回调方法的内容如下:

function onRestaurantSeachSuccess(searchResult) //searchResult为请求返回的数据 
{
    var restaurantContainer = document.getElementById("restaurantList");
    restaurantContainer.innerHTML = "";
    
    for (var i=0; i<searchResult.length; i++) //绑定数据并进行显示
    {
        var restaurantHtml= "<a href=\"javascript:restaurantSelection_Click('"
                + searchResult[i].RestaurantId + "', '"
                + searchResult[i].LogoImageLocation +"', '"
                + searchResult[i].Name +"');\"><img src=\""
                + searchResult[i].LogoImageLocation + "\" alt=\""
                + searchResult[i].Name + "\" width=\"154\" height=\"90\" class=\"thingreenline\" /></a>";
        var restaurantElement=document.createElement("span");
        restaurantElement.innerHTML = restaurantHtml;
        
        restaurantContainer.appendChild(restaurantElement);
    }
    
   DisplayDiv("SearchResultsDivision");
}

  通过这个方法的调用实现了上面图中的显示效果,当我们单击了其中某个餐馆的图标之后.
会显示下面的页面:

而单击事件的执行方法如下:

function restaurantSelection_Click(identifier, logo, name)
{
    /********** RestaurantSelected ***********/生成餐馆的信息,如LOGO,餐馆名称,说明等
    document.getElementById("restaurantImage").src = logo;
    document.getElementById("restaurantName").innerHTML = name;
 
    document.getElementById("restaurantDescription").innerHTML = "Since 1923, the offering fas, friendly and courteous service.  We use only the best ingredients and maintain a skilled staff to answer your questions.  We have built our reputation on our commitment to providing quality service, which has earned us many valuable customers.";
   
    document.getElementById("restaurantMenuFeed").href = "service/syndication.svc/rss/restaurants/"+ name;
   
    var restaurant = document.getElementById("restaurantID");
    restaurant.innerHTML = identifier;
    /********** RestaurantSelected ***********/
    
    var service = new DinnerNow.Services.IMenuSearchService();//加载菜单列表
    var menuType = return_MenuType();
    var selectedMenuType = document.getElementById("selectedMenuItemCategory");
    selectedMenuType.value = menuType;
    service.GetMenuItemsForMenu(identifier,menuType,restaurantSelection_onSuccess,restaurantSelection_onFailed,null);//请求并加载菜单列表
    service.GetMenuTypes(getMenuTypes_onSuccess, getMenuTypes_onFailed, null);//加载菜单类型(上图中的属性页:Breakfast,Dinner,Lunch)
}

其中的GetMenuItemsForMenu,GetMenuTypes方法最终会去调用MenuSearchService类中的同名方法(MenuSearchService.cs文件在DinnerNow.ServicesDinnerNow - ServicePortfolio2.sln解决方案),所以这里我们还要再切换到ServicePortfolio2.sln下,找到位于DinnerNow.Services项目下的MenuSearchService.cs文件。其中的GetMenuItemsForMenu方法定义如下:

 public IEnumerable<DinnerNow.Business.Data.RestaurantMenuItem> GetMenuItemsForMenu(string restaurantId, string menuType)
 {
     Business.Menu menu = new DinnerNow.Business.Menu();
     return menu.GetMenuItemsForMenu(new Guid(restaurantId), menuType);//获取指定类型的菜单数据
 }

代码段中的menu.GetMenuItemsForMenu方法定义如:   

public IEnumerable<DinnerNow.Business.Data.RestaurantMenuItem> GetMenuItemsForMenu(Guid restaurantId, string menuType)
{
    var results = from mi in db.MenuItems
                  join m in db.Menus on mi.MenuId equals m.MenuId
                  where m.RestaurantId == restaurantId
                  && m.MenuType == menuType
                  select new Business.Data.RestaurantMenuItem()
                  {
                      Description = mi.Description,
                      ImageLocation = mi.ImageLocation,
                      MenuId = mi.MenuId,
                      MenuItemId = mi.MenuItemId,
                      Name = mi.Name,
                      PreparationTime = mi.PreparationTime,
                      Price = mi.Price
                  };
    return results.ToList();
}

  上面的LINQ查询相当于下面的SQL脚本:

SELECT [t0].[MenuItemId], [t0].[MenuId], [t0].[Name], [t0].[Description], [t0].[ImageLocation], [t0].[Price], [t0].[PreparationTime]
FROM [dbo].[MenuItem] AS [t0]
INNER JOIN [dbo].[Menu] AS [t1] ON [t0].[MenuId] = [t1].[MenuId]
WHERE ([t1].[RestaurantId] = @p0) AND ([t1].[MenuType] = @p1)

  而前面所说的GetMenuTypes方法大家也可以找到它最终要去访问的LINQ代码如下:

public IEnumerable<DinnerNow.Business.Data.MenuType> GetMenuTypes()
{
      var s = (from m in db.Menus
              select new DinnerNow.Business.Data.MenuType()
              {
                  MenuTypeName = m.MenuType.Trim() 
              }).Distinct();
      return s.ToList();
}

这里因为代码很简单,就不多说了.

  通过这个业务流程可以看出DinnerNow基本架构思想:
ajax 请求数据 ---> wcf 服务配置  ---> linq 数据访问.

这样架构让整个软件的架构,流程及开发层次非常清楚。另外因为使用了 Ajax Extensions,使得开发和阅读JS代码感觉就像是在写C#代码,使得软件的可读性和可维护性上也有很好提升和扩展空间.另外就是在UE上也使在我们可以在一个页面上完成挑选餐馆,选择食物并进行订餐的整个流程(接下来将会依次说明).避免了频繁提交页面请求而导致的操作繁锁和服务器访问超时问题,以及用户等待时间过长(体验差)和其它易于出错的问题.

  下面接着上面的JS代码中的GetMenuItemsForMenu请求的回调方法restaurantSelection_onSuccess来继续我们的操作流程:

 //绑定菜单列表数据并进行显示
function restaurantSelection_onSuccess(result)
{
    var menuItemContainer = document.getElementById("menuList");
    menuItemContainer.innerHTML = "";

/******** MenuItems **********/            
    for (var i=0; i<result.length; i++)
    {
        var menuItem = result[i];
        
        var menuItemHtml = "<table width='100%' border='0' align='center' cellpadding='8' cellspacing='0' class='thinblueline'><tr><td width='150' align='center' valign='top'><div class='hoverarea'><div><a href=\""
                + menuItem.ImageLocation + "\" target='_blank'> <img id=\"MenuItemImage\" src=\""
                + menuItem.ImageLocation + "\" alt=\""
                + menuItem.Name +"\"/><img id=\"Img1\" src=\""
                + menuItem.ImageLocation+ "\" alt=\""
                + menuItem.Name+"\" class=\"hoverimage_preview\"/></a></div></div></td><td valign='top'><strong>Item # "
                + i + "</strong><br/><strong>"
                + menuItem.Name+"</strong><br/>"
                + menuItem.Description+"<br/><br/><div align='left'><strong>Estimated Delivery Time: "
                + menuItem.PreparationTime+" minutes</strong></div></td><td width='80' align='right' valign='top'><strong>$"
                + menuItem.Price+"</strong><br/><br/><a class=\"noUnderline\" href=\"javascript:AddItemToShoppingCart('"
                + menuItem.Description + "', '"
                + menuItem.ImageLocation + "', '"
                + menuItem.MenuId + "', '"
                + menuItem.MenuItemId + "', '"
                + menuItem.Name + "', '"
                + menuItem.PreparationTime + "', '"
                + menuItem.Price + "');\"><img src=\"images/selectbutton.gif\" border=\"0\" /></a></td></tr></table>";
                
        var menuItemElement=document.createElement("span");
        menuItemElement.innerHTML = menuItemHtml;
    
        menuItemContainer.appendChild(menuItemElement);
    }
    /******** MenuItems **********/
    
    DisplayDivContent4("shoppingCart");
    DisplayDiv("MenuDivision");
}

  看到这里,我们在回到页面上看一下当我们单击菜单旁边的"select"按钮之后所显示的页面内容:

  而单击所执行的JS方法如下(该方法用于将订餐数据加载到购物车中):

function AddItemToShoppingCart(description,imageLocation,menuId,menuItemId,name,preparationTime,price)
{
    var menuItem = new DinnerNow.Business.Data.RestaurantMenuItem();

menuItem.Description = description;
    menuItem.ImageLocation = imageLocation;
    menuItem.MenuId = menuId;
    menuItem.MenuItemId = menuItemId;
    menuItem.Name = name;
    menuItem.PreparationTime = preparationTime;
    menuItem.Price = price;

var restaurant = new DinnerNow.Business.Data.RestaurantHeader();
    
    restaurant.RestaurantId = document.getElementById("restaurantID").innerHTML;
    restaurant.Name = document.getElementById("restaurantName").innerHTML;
    restaurant.LogoImageLocation = document.getElementById("restaurantImage").src;

DinnerNow.ShoppingCartService.AddItem(menuItem,restaurant,menuSort,addItemToShoppingCart_onSuccess,addItemToShoppingCart_onFailed,null);
}

其中的DinnerNow.ShoppingCartService.AddItem调用会生成如下的ajax请求:

AddItem:function(selectedItem,restaurant,selectedSortOption,succeededCallback, failedCallback, userContext) {
/// <param name="selectedItem" type="DinnerNow.Business.Data.RestaurantMenuItem">DinnerNow.WebUX.MenuSearchService.RestaurantMenuItem</param>
/// <param name="restaurant" type="DinnerNow.Business.Data.RestaurantHeader">DinnerNow.WebUX.MenuSearchService.RestaurantHeader</param>
/// <param name="selectedSortOption" type="Number">System.Int32</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
return this._invoke(this._get_path(), 'AddItem',false,{selectedItem:selectedItem,restaurant:restaurant,selectedSortOption:selectedSortOption},succeededCallback,failedCallback,userContext); }

  而最终ajax请求会成为对如下方法的调用(DinnerNow.WebUX\Code\ShoppingCartService.cs文件中):

[OperationContract]
public List<ShoppingCartItem> AddItem(RestaurantMenuItem selectedItem, RestaurantHeader restaurant, int selectedSortOption)
{
    ShoppingCartItem shoppingCartItem = new ShoppingCartItem()
    {
        DeliveryTime = selectedItem.PreparationTime,
        MenuItemIdentifier = selectedItem.MenuItemId.ToString(),
        MenuItemName = selectedItem.Name,
        PreparationTime = selectedItem.PreparationTime,
        Price = selectedItem.Price,
        Quantity = 1,
        RestaurantIdentifier = restaurant.RestaurantId.ToString(),
        RestaurantImageLocation = restaurant.LogoImageLocation,
        RestaurantName = restaurant.Name,
        RestaurantItem = selectedItem,
        Restaurant = restaurant
    };
    shoppingCart.AddItem(shoppingCartItem);

return this.RefreshItems(selectedSortOption);
}

   通过这个方法我们可以实现将选定的食物放入购物车,并将购物车中已有商品的类型,价格,数据等信息返回到请求页面中.并通过下面的JS方法来显示相应的数据信息.

function _refreshShoppingCart(result)
{
    var shoppingCartContainer = document.getElementById("shoppingCartList");
    shoppingCartContainer.innerHTML = "";
    
    var restaurantId = "";
    var firsth = true;
    
    var html = "";

/******** Shopping Cart Items **********/
    for (var i=0; i<result.length; i++)
    {
        var shoppingCartItem = result[i];
        var subtotal = (shoppingCartItem.Price * shoppingCartItem.Quantity);//商品价格*数量
        var restaurantItemHtml="";
        var endPrevRestaurantItemHtml ="";
        
        if (restaurantId != shoppingCartItem.RestaurantIdentifier && menuSort != 1)
        {
            if (!firsth)
                endPrevRestaurantItemHtml = "</table></td></tr>";
            
            firsth = false; 
            restaurantId = shoppingCartItem.RestaurantIdentifier;
            restaurantItemHtml = "<table width='100%' border='0' align='center' cellpadding='4' cellspacing='4' bgcolor='#5686B4' class='thinblueline'><tr><td align='left' bgcolor='#31465B' class='boldWhite'>"
                    + shoppingCartItem.RestaurantName + "</td></tr><tr><td>";
        }
       
        var shoppingCartHtml = "<table width='100%' border='0' cellspacing='2' cellpadding='2' bgcolor='#5686B4'><tr><td align='left'><a class='noUnderline' href=\"javascript:DeleteItemFromShoppingCart('"
                + shoppingCartItem.MenuItemIdentifier + "');\"><img src='images/delete.gif' alt='Remove item' width='17' height='16'/></a></td><td align='left' width='60%'>"
                + shoppingCartItem.MenuItemName + "</td><td align='left'><input type='text' id='"
                + shoppingCartItem.MenuItemIdentifier + "_itemViewQuantityBox' size='2' class='checkOutFormsField' οnchange=\"updateShoppingCartQuantity('"
                + shoppingCartItem.MenuItemIdentifier + "');\" value ='"
                + shoppingCartItem.Quantity + "'></input></td><td align='left' nowrap='nowrap' class='bodyTextWhite'> $"
                + subtotal + "</td></tr>";
         
         html += endPrevRestaurantItemHtml+restaurantItemHtml+shoppingCartHtml+"</table><br/>";
    }
    /******** Shopping Cart Items **********/

if (html != "")
        html+="</td></tr></table>";
        
    var shoppingCartElement=document.createElement("span");                   
    shoppingCartElement.innerHTML = html;
    
    shoppingCartContainer.appendChild(shoppingCartElement);
    //ajax调用计算购物车中的Total,ETA信息
    DinnerNow.ShoppingCartService.Totals(getTotals_onSuccess, getTotals_onFailed,null);
}

可以看出,整个选购流程还是有些复杂的,但在操作上却很流畅,让人感觉不出什么繁锁.这其实都要得益于ajax的适当应用.当然微软的Ajax Extensions无形中也降低了AJAX代码的开发门槛:)

  在下一篇文章中,我们将会继续订餐流程,不过重点将会转移动到DinnerNow - ServicePortfolio2.sln解决方案下,并且因为DinnerNow中使用了WWF(Windows Work Flow Foundation), 所以下一篇文章的内容可能会更偏向于WWF。如果大家感兴趣的话,敬请留意:)

  好了,今天的文章就先到这里了,如果大家有什么问题欢迎与我交流.

本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/339019,如需转载请自行联系原作者

DinnerNow中的ASP.NET Ajax Extensions应用---选餐流程相关推荐

  1. 《ASP.NET AJAX程序设计 第I卷 服务器端ASP.NET AJAX Extensions与ASP.NET AJAX Control Toolkit》目录(最终定稿)...

    第一二卷都比较简单,特别是第一卷,讲的都是服务器端控件.第二卷是客户端部分,第三卷是高级内容,包括调试.性能.部署.控件开发.源代码结构.用户体验.心理学模型等等-- 第一卷争取在四月份出版,谢谢各位 ...

  2. ASP.NET AJAX 在Web开发中的应用

    摘 要 ASP.NET AJAX 实现了Web页面丰富的部分刷新效果.本文通过介绍AJAX原理,引申到ASP.NET AJAX原理,并总结了在Web 开发应用中要注意的若干问题.合理地利用ASP.NE ...

  3. DinnerNow中的Work Flow应用(下) --- 订单流程

    做为微软最新技术应用的DEMO.dinnernow使用了: IIS7, ASP.NET Ajax Extensions, LINQ, WCF, WF,WPF,Windows PowerShell, C ...

  4. ASP.NET AJAX环境的简单构建(ZT)

    1 概述 Microsoft ASP.NET AJAX 是 Microsoft 公司对 Ajax 技术的完美封装.它能使你已快速的创建包含丰富用户体验的用户界面的 Web 页面,提供加入了跨浏览器的 ...

  5. Msdn 杂志 asp.net ajax 文章汇集

    asp.net ajax 充分利用客户端 JavaScript.DHTML 和 XMLHttpRequest 对象.其目的是帮助开发人员创建更具交互性的支持 AJAX 的 Web 应用程序 ASP.N ...

  6. [翻译]ASP.NET AJAX与SharePoint的集成

    原文: Integrating ASP.NET AJAX with SharePoint 来自微软SharePoint Team Blog Microsoft ASP.NET AJAX 1.0: 一点 ...

  7. 开始使用asp.net ajax的控件工具包AJAX Control Toolkit

    我们来为我们的 toolbox 添加一些资源 , 这个要通过下载安装 asp.net ajax 工具包完成.登录 www.asp.net 点击 AJAX 按钮,然后找到 ASP.NET AJAX Co ...

  8. 初学 ASP.NET AJAX (一):构建 ASP.NET AJAX 开发环境

    1 概述 Microsoft ASP.NET AJAX 是 Microsoft 公司对 Ajax 技术的完美封装.它能使你已快速的创建包含丰富用户体验的用户界面的 Web 页面,提供加入了跨浏览器的 ...

  9. ASP.NET AJAX (Atlas) 拖放(Drag Drop)功能6种实现方法总结

    在Ajax程序中实现传统桌面程序中异常简单的拖放功能却并不是件容易的事情.然而Web上的拖放功能又如此的让人痴迷,所以几乎每个成熟的Ajax类库都提供了自己的一套实现拖放的封装,ASP.NET AJA ...

最新文章

  1. Acronis移动方案(四)
  2. python 命令行参数-Python3 命令行参数
  3. redis 数据结构
  4. javafx树视图加选框_JavaFX缺少的功能调查:表视图
  5. python调用摄像头人脸识别代码_OpenCV3-Python人脸识别方法—人脸识别与标记
  6. php 事务回滚,php实现事务回滚的方法
  7. VC使用命令行编译很复杂
  8. 190312每日一句
  9. Jupyter notebook:如何切换Python环境
  10. 《OpenGL编程指南》 笔记一 OpenGL概述
  11. 第七次人口普查数据可视化分析实战——基于pyecharts(含数据和源码)
  12. 7.3万字肝爆Java8新特性,我不信你能看完!(建议收藏)
  13. 视频下载软件Annie的安装及使用
  14. 用styler更改样式后,解决数据框中数据无法保留四位小数
  15. 现代笑话二则2 木子家创作
  16. OpenCASCADE 读写STEP文件
  17. pytorch版本下的yolov3训练实现火焰检测
  18. Linux搭建SVN Server
  19. 根据LocalDate或者DateUtils计算两个日期之间的天数差
  20. 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器

热门文章

  1. 操作系统swap对redis的性能的影响以及解决方案
  2. tomcat ng mysql 集成_整合nginx,tomcat,mysql的安装与配置
  3. keil5 仿真usart窗口没有限制_多体仿真:DS SIMULIA Simpack 2021
  4. php 怎样让 键 值 反转,PHP 控制和反转
  5. java连接mysql数据库时出现乱码_java连接mysql数据库中文乱码问题
  6. python如何调用阿里云接口_阿里云 API调用实践(python语言)
  7. 手部骨骼特征 数据集_速写局部精讲之手部比例、肌肉、特征解析
  8. python 重启电脑_如何在系统重启后恢复Python脚本?
  9. 数组指定位置添加元素_访问数组的任意位置元素的性能真的一样?
  10. python在docx指定位置插表格_超简单Python将指定数据插入到docx模板指定位置渲染并保存...