65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 jQuery Mobile 在 ASP.NET MVC 4 中开发移动专用视图 - 第 1 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (22投票s)

2014年3月6日

CPOL

9分钟阅读

viewsIcon

57002

downloadIcon

2117

使用 jQuery Mobile 在 ASP.NET MVC 4 中开发移动专用视图 - 第 1 部分

引言

本文介绍了如何使用 ASP.NET MVC 开发一个同时包含移动专用视图和桌面视图的 Web 应用程序。针对移动设备的 UI 设计与针对桌面屏幕的设计非常不同。我们使用 jQuery Mobile 来开发移动视图。

目录

本文分为以下两部分

第一部分

  • 为什么我们需要单独的移动视图
  • 演示应用程序概述
  • 从 Internet 模板开始
  • 安装 51Degrees.mobi
  • 创建模型和控制器
  • 创建视图
  • 运行应用程序

第二部分

  • 安装 jQuery Mobile
  • 为移动视图创建捆绑包
  • 为移动视图设计布局
  • 为移动设备设计产品页面
  • 为移动设备设计按类别划分的产品页面

在这里,我们将介绍第 1 部分的内容。让我们开始吧。

为什么我们需要单独的移动视图

设计移动网页需要与桌面网页不同的方式,主要有两个原因:

  1. 与桌面/笔记本电脑屏幕相比,移动屏幕上的显示空间非常有限。
  2. 触摸操作的精度不如鼠标。使用鼠标可以点击小的文本链接,但用拇指或手指则困难,有时甚至不可能。

正如 此链接所描述的,在针对移动设备设计 Web 应用程序时,还有更多需要考虑的因素。如今,我们也有了设计多平台形态的概念,正如 这篇博文所讨论的。

但为了简化本文的演示,我们不会深入探讨这些细节。本文中,我们将只考虑两个类别:典型的桌面页面,用户拥有宽阔的显示屏和典型的鼠标和键盘;移动页面,用于移动设备/平板电脑,用户拥有较小的显示屏和触摸屏来与网页交互。

演示应用程序概述

在演示应用程序中,我们将创建一个 Web 应用程序来显示可用的产品。应用程序的默认页面将显示所有可用的产品,我们还有另一个页面根据类别的选择来筛选产品。该应用程序将有两个视图版本:桌面视图和移动视图。为了简单起见,我们将使用硬编码数据来显示在网页上。对于移动专用视图,我们将在第 2 部分中使用 jQuery Mobile,而在本部分中,我们将创建没有 jQuery Mobile 的移动视图。

由于我们有两个页面包含几乎相同的信息,因此我们必须根据发送请求的环境/浏览器来渲染特定的视图。如果请求来自移动浏览器,则会渲染移动专用视图,否则应用程序将为桌面浏览器渲染普通视图。为了在服务器端检测请求来自哪个环境/浏览器,我们将使用 51Degrees.mobi 来检测请求浏览器的用户代理。我们将在后面的章节中进一步讨论这一点。

最后,为了测试该应用程序,特别是移动设备的网页,我们需要一个移动设备模拟器,或者我们可以使用可以像移动设备浏览器一样运行的浏览器。为此,我正在使用 Safari 浏览器用户代理切换器来测试这两种视图。我们将在本文的最后部分“运行应用程序”中进一步讨论这一点。

从 Internet 模板开始

  1. 让我们创建一个示例应用程序,选择 ASP.NET MVC4 Web Application 模板,将项目名称命名为 ShopOnline,然后单击“OK”。

    Alternate way to achieve Modularization

  2. 选择项目模板为 Internet Application。Visual Studio 2012 会在解决方案中添加一个 ShopOnline 项目,如下图所示。

    Alternate way to achieve Modularization

安装 51Degrees.mobi

传入 HTTP 请求的用户代理头标识了向服务器请求信息的应用程序,通常是浏览器。用于标识的字符串称为用户代理字符串,其中包含提供有关发出请求的程序的具体细节的令牌。要了解更多关于用户代理的信息,请访问此处
检测浏览器有两种最常用的选项:

  1. 通过在 App_Start 中注册 Display Mode,如 这篇博文所述。
  2. 使用 51Degrees.mobi。使用此库的设备数据,应用程序可以获取准确的屏幕尺寸、输入方法以及制造商和型号信息。

我们将在本文中使用 51Degrees.mobi。安装 51Degrees.mobi 有两种方法:使用 Nuget 包管理器控制台或使用 Nuget 包管理器工具。这里我们将通过 Nuget 包管理器工具进行安装。NuGet 是一个开源包管理器工具,内置于 Visual Studio 2010 和 2012 中。它可以下载包和所需的依赖项。以下是下载 51Degrees.mobi 的步骤:

  1. 在菜单栏中单击 TOOLS,然后选择“Library Package Manager”,再选择“Manage NuGet Packages for Solution”选项,如下图所示。

    NuGet Manager UI

    在左侧菜单中,选择 Online > All。现在点击右侧(顶部)的搜索文本框,输入“51”,搜索结果中会显示 51.Degrees.mobi,如下图所示。点击 51.Degrees.mobi 旁边的 Install 按钮。

    51Degrees.mobi Install

    会弹出一个项目名称确认窗口,如下图所示,只需点击 OK。

    Project Confirmation

  2. 希望您能在项目中看到“51Degrees.mobi.config”文件,如下图所示。

    51Degrees.mobi Installed

  3. 默认情况下,它会在应用程序中创建一个“mobile”文件夹。我们应该删除这个不必要的文件夹,并将我们的移动视图保留在 Views 文件夹中。
  4. 打开 51Degrees.mobi.config 文件,并 **注释掉** 以下代码行(因为它会将来自移动设备的请求重定向到“~/mobile/default.aspx”,而我们不想要这样做)。
    <redirect    
        firstRequestOnly="false" 
        mobileHomePageUrl="~/mobile/default.aspx"
        timeout="20"
        devicesFile="~/App_Data/Devices.dat"
        mobilePagesRegex="mobile">
    </redirect>

使用 Nuget 包管理器控制台

安装 51Degrees.mobi 的另一种方法是使用“Nuget Package Manager Console”。您需要转到顶部菜单“TOOLS > Library Package Manager > Package Manager Console”,如下图所示。

NuGet Console UI

它将打开一个控制台窗口。现在您需要运行以下命令:Install-Package 51Degrees.mobi,如下图所示。

Run Command for 51Degrees.mobi

这将完成与步骤 1 相同的操作。所有在步骤 2 中显示的内容都会被添加,然后您需要按照步骤 3 和 4 删除不必要的文件夹和设置。如果您想了解更多关于 51Degrees.mobi 如何工作的信息,请访问 此处,并查看“它如何工作?”部分。

创建模型、ViewModel 和控制器

  1. Models 文件夹内,添加三个名为 CategoryProductDataRepository 的类文件。
  2. Category.cs 中,添加以下代码
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
    }
  3. Product.cs 中,添加以下代码
    public class Product
    {
        public int ProductId { get; set; }    
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public Category ProductCategory { get; set; }
    }
  4. DataRepository.cs 中,添加以下代码
    public class DataRepository
        {
            public List<Product> GetProducts()
            {
                List<Product> products = new List<Product>{ 
                        new Product () { ProductId = 1, ProductName = "Nokia Lumia 625", 
                            ProductDescription = "A mid-range Lumia with a focus of 
                            combining 4G with a large display (4.7 inch, the first time 
                            on a Lumia), yet keeping the price in a low and affordable range",
                        ProductCategory =  new Category () { CategoryId = 1, CategoryName = "Phones"}},
        
                        new Product () { ProductId = 2, ProductName = "Nokia Lumia 925", 
                            ProductDescription = "A thinner, lighter, partially aluminium 
                            re-skin of the Lumia 920, designed to broaden the appeal of the 92x range. 
                            It is a compromise between Lumia 920 and Lumia 928 features-wise.",
                        ProductCategory =  new Category () { CategoryId = 1, CategoryName = "Phones"}},
                        
                        new Product () {ProductId = 3, ProductName = "ThinkPad X1 Carbon Ultrabook", 
                            ProductDescription = "At less than 1.4 kg, the X1 Carbon Ultrabook™ 
                            brings a new level of quality to the ThinkPad legacy of high standards 
                            and innovation. A carbon fiber roll cage with reinforcement 
                            throughout makes this system ultralight, ultradurable, 
                            and highly portable. Stay unplugged all day, but when needed, 
                            boost your battery up to 80% capacity in just 35 minutes.",
                        ProductCategory = new Category () {CategoryId = 2, CategoryName = "Computers"}},
     
                        new Product () {ProductId = 4, ProductName = "ThinkPad X230 Laptop", 
                            ProductDescription = "Tough, slim and light, 
                            the 12.5 inch ThinkPad X230 elevates the business laptop to a new level 
                            with its vivid IPS display, purer sound and peerless keyboard ergonomics. 
                            Start faster, resume faster and charge your battery less, 
                            giving you more time to strive for success.",
                        ProductCategory = new Category () {CategoryId = 2, CategoryName = "Computers"}},
                        
                        new Product () {ProductId = 5, ProductName = "Programming ASP.NET MVC 4", 
                            ProductDescription = "Get up and running with ASP.NET MVC 4, 
                            and learn how to build modern server-side web applications. 
                            This guide helps you understand how the framework performs, 
                            and shows you how to use various features to solve many real-world 
                            development scenarios you’re likely to face.",
                        ProductCategory = new Category () {CategoryId = 3, CategoryName = "Books"}},
                        
                        new Product () {ProductId = 6, ProductName = "Pro ASP.NET MVC 4", 
                            ProductDescription = "In this fourth edition, 
                            the core model-view-controller (MVC) architectural concepts are not 
                            simply explained or discussed in isolation, but are demonstrated in action. 
                            You’ll work through an extended tutorial to create a working e-commerce 
                            web application that combines ASP.NET MVC with the latest 
                            C# language features and unit-testing best practices.",
                        ProductCategory = new Category () {CategoryId = 3, CategoryName = "Book"}}
               };
               
                return products;
            }
            
            public List<Category> GetCategories()
            {
                return new List<Category> {
                new Category () { CategoryId = 1, CategoryName = "Phones"},
                new Category () {CategoryId = 2, CategoryName = "Computers"},
                new Category () { CategoryId = 3, CategoryName = "Books"}
                };
            }
        }                

    为了简单起见,我们在 Repository 中使用了硬编码数据作为演示目的。在实际应用程序中,Repository 应该通过与 SQL Server、XML 或任何其他持久数据源通信来进行 CRUD 操作。对于此演示,我们的模型和 Repository 现在已准备好使用。

  5. 现在我们将创建一个 ViewModel,因为我们需要将 Category Product 模型都传递给“Category wise Products”页面。要了解更多关于 ViewModel 的信息,请访问 本文档的“ViewModel”部分。现在,通过右键单击项目 > Add > New Folder 在项目中添加一个“ViewModels”文件夹,如下图所示。

    Adding ViewModel Folder

  6. ViewModels 文件夹内,添加一个名为“ProductCategoryVM”的类,并在其中添加以下代码。
    public class ProductCategoryVM
    {
        public int SelectedCategoryId = -1;
        public List<Category> AllCategories { get; set; }
        public List<Product> AllProducts { get; set; }
    }
  7. Controllers 文件夹中,添加一个名为“ProductController”的新空控制器,如下图所示。

    Adding Product Controller

  8. 将以下代码添加到 ProductController 类中,并根据需要添加适当的命名空间。
    DataRepository _repository = new DataRepository();
    
    public ActionResult AllProducts()
    {
        List<Product> productModel = new List<Product>();
        productModel = _repository.GetProducts();
        return View(productModel);
    }
    
    public ActionResult CategoryWiseProducts()
    {
        ProductCategoryVM vm = new ProductCategoryVM();
        vm.AllCategories = _repository.GetCategories();
        vm.AllProducts = _repository.GetProducts();
        return View(vm);
    }

创建视图

我们将为 Controller 中的每个动作方法创建两个视图:一个专为桌面设计,第二个为移动设备设计。目前,在移动专用视图中,我们只会写一段文字,说明它是移动专用视图。我们将在本文的第 2 部分安装 jQuery Mobile,进行设计并完成移动专用视图。

请按照以下步骤添加视图:

  1. 首先,构建项目(否则模型类在创建视图时将不会出现在列表框中)。现在,在 ProductController 上,右键单击“AllProducts”动作方法,然后从菜单中选择“Add View”。您将看到一个如下所示的弹出窗口,填写此处显示的信息,然后单击 OK。

    Adding Product View

    这将在 Views > Product 文件夹中添加 AllProducts.cshtml

  2. AllProducts.cshtml 中,删除标题和下面的“Create New”操作链接,因为我们不会使用它们。
                         <h2>All Products</h2>
                         <p>@Html.ActionLink("Create New", "Create") </p>

    添加一个新表格(替换被删除的“Create New”操作链接),如下所示。

     <table >
        <tr>
             <td style="width:20%; text-align:left;">
                <h2>All Products</h2>
            </td>
            <td style="width:90%; text-align:right;">
                @Html.ActionLink("Category wise Products", 
                "CategoryWiseProducts", "", 
                new { style = "font-size:20px; background-color:lightblue;" })
            </td>
        </tr>
    </table>                 

    现在,更新现有表格以显示产品详细信息。首先,将表格标题代码更新为以下内容:

    <tr>
        <th>Name
        </th>
        <th>Description
        </th>
    </tr>

    并删除 Product 表格中下方操作链接的代码,因为我们不会为这些实现任何功能。

    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
        @Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.ProductId })
    </td>                 
  3. 现在再次转到 ProductController ,右键单击“CategoryWiseProducts”动作方法,然后从菜单中选择“Add View”。这次我们将看到一个如下所示的弹出窗口,填写此处显示的信息(我们将选择空视图,因此取消选中“Create a strongly-typed view”复选框),然后单击 OK。

    Adding Category wise Products View

    在新添加的视图 CategoryWiseProducts.cshtml 中写入以下代码。

    @model ShopOnline.ViewModels.ProductCategoryVM
    @{
        ViewBag.Title = "Category wise Products";
        SelectList cat = new SelectList(Model.AllCategories, "CategoryId", "CategoryName");  
    }
    
    <h2>Category wise Products</h2>
    <br />
    <table>
        <tr>
            <td style="font-size: 16px;">Select a Category:
            </td>
            <td>
                @Html.DropDownListFor(m => m.SelectedCategoryId, cat, 
                "Select Category", new { style = "width:200px; font-size:16px;" })
            </td>
        </tr>
    </table>
    
    <table>
        <tbody id="tblProductData">
        </tbody>
    </table>
    
    <script>       
        $("#SelectedCategoryId").change(function () {                    
            var selectedCategory = $(this).val().trim();             
            var allProducts = @Html.Raw(Json.Encode(Model.AllProducts));            
            
            $('#tblProductData').empty();
            var headers = '<tr><th>Name</th><th>Description</th></tr>';           
            var elements = "";
            for (var i = 0; i < allProducts.length; i++) {
                 if(allProducts[i].ProductCategory.CategoryId == selectedCategory)
                    elements = elements + '<tr><td>' + 
                    allProducts[i].ProductName + '</td><td>' + 
                    allProducts[i].ProductDescription + '</td></tr>';
             }             
            if (elements != "")
                $('#tblProductData').append(headers + elements);
        });   
    </script>
  4. 在 Views > shared 文件夹下的 _Layout 页面中,更改以下行的位置:
    @Scripts.Render("~/bundles/jquery")

    默认情况下,它在底部,将其放在布局页面的 head 中。删除不必要的链接和代码,最终效果如下:

    <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="utf-8" />
                <title>@ViewBag.Title - My ASP.NET MVC Application</title>       
                <meta name="viewport" content="width=device-width" />
                @Scripts.Render("~/bundles/jquery")
                @Styles.Render("~/Content/css")
                @Scripts.Render("~/bundles/modernizr")
            </head>
            <body>
                <header>
                    <div class="content-wrapper">
                        <div class="float-center">                    
                            <nav>
                                <ul id="menu">
                                    <li>@Html.ActionLink
                                    ("Home", "Index", "Home")</li>
                                    <li>@Html.ActionLink("Products", 
                                    "AllProducts", "Product")</li>                            
                                </ul>
                            </nav>
                        </div>
                    </div>
                </header>
                <div id="body">           
                    <section class="content-wrapper main-content clear-fix">
                        @RenderBody()
                    </section>
                </div>       
            </body>
        </html>
  5. 现在,在 Views > Product 文件夹中,复制 AllProducts.cshtmlCategoryWiseProducts.cshtml,然后通过右键单击 Product 文件夹本身进行粘贴。您将得到“Copy of AllProducts.cshtml”和“Copy of CategoryWiseProducts.cshtml”,分别重命名为“AllProducts.Mobile.cshtml”和“CategoryWiseProducts.Mobile.cshtml”。

    将两个“AllProducts.Mobile.cshtml”的 <h2> 标签更改为“All Products : Mobile View”,同样将“CategoryWiseProducts.Mobile.cshtml”更改为“Category Wise Product : Mobile View”。

    这样做的目的是为了识别是否来自移动设备的请求,从而渲染 .Mobile.cshtml 视图。我们将在本文的下一部分中设计和优化这些针对移动屏幕的视图。

  6. 最后,我们需要更改应用程序的默认页面,所以转到 App_Start > RouteConfig.cs,在 RegisterRoute 方法中,将默认路由更改为:
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Product", 
            action = "AllProducts", id = UrlParameter.Optional }
        );
    }               

运行应用程序

测试移动视图最简单的方法是使用 Safari 浏览器,因为它内置了用户代理切换器。请访问 此链接以了解如何激活和使用它。对于这个应用程序,我使用了 Safari 并只为此拍摄了截图。

如果您使用的是 Chrome,可以使用扩展程序 User-Agent Switcher for Chrome。有很多关于如何使用它的资源。如果您不想安装任何新东西,甚至可以不安装任何附加工具来更改用户代理,如 此处所述。此外,您还可以使用模拟器或其他技术,如 此处所述。

使用 Safari 浏览器内置的用户代理切换器,您可以看到我们到目前为止开发的“Category wise Products”两种视图的输出,如下图所示。

桌面视图

Web Page for Desktop

现在将用户代理更改为以下内容:

Changing User Agent

我们可以看到移动视图

Web Page for Mobile

结论

在本文中,我们演示了 51Degrees.mobi 的使用方法,以及它如何自动检测传入请求并渲染适当的视图。在 第 2 部分中,我们将以本文开发的应用程序为基础,首先安装 jQuery Mobile,然后继续开发移动专用屏幕。欢迎您提出任何疑问和评论。谢谢。

© . All rights reserved.