程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> DinnerNow中的ASP.NET Ajax Extensions應用---選餐流程

DinnerNow中的ASP.NET Ajax Extensions應用---選餐流程

編輯:關於.NET

繼上一篇文章DinnerNow中的WCF應用 --- 首頁數據加載,我們大概了解了一些關於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' onchange=\"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。如果大家

感興趣的話,敬請留意:)

好了,今天的文章就先到這裡了,如果大家有什麼問題歡迎與我交流.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved