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

AngularJS 入门 - 第二部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (8投票s)

2015年10月28日

CPOL

4分钟阅读

viewsIcon

17351

downloadIcon

340

本文将演示如何开始使用AngularJS开发网站。通过HTTP方法连接服务器数据库。

引言

在之前的文章AngularJS入门 - 第一部分中,我们看到了AngularJS中使用内存数组的CRUD示例。在本文中,我将继续使用相同的示例,但现在我们将使用服务器端数据存储。出于本文的目的,我使用了嵌入式数据库SQL Server Compact Edition。我使用asp.net-webapi作为与服务器端通信的机制。

背景

Microsoft SQL Server Compact (SQL CE) 是微软生产的一种紧凑型关系数据库,用于运行在移动设备和桌面上的应用程序。它与其他Microsoft SQL Server版本共享一个通用的API。它还包括用于使用ADO.NET API访问数据的ADO.NET提供程序,以及对LINQ和Entity Framework的支持。SQL CE数据库驻留在单个.sdf文件中,大小可达4 GB。.sdf文件可以简单地复制到目标系统进行部署。它还支持DataDirectories,使用SQL CE数据库的应用程序无需在ADO.NET连接字符串中指定.sdf文件的完整路径,而可以将其指定为|DataDirectory|\.sdf.

如果您尚未安装它,可以从Microsoft SQL Server Compact 4.0下载。

ASP.NET Web API支持使您可以轻松创建功能强大的Web API,这些API可以从各种客户端访问(从使用JavaScript的浏览器到任何移动/客户端平台上的原生应用程序)。有关ASP.NET WebAPI的更多详细信息和教程,您可以访问此链接

Using the Code

让我们从代码开始,首先我更改了此应用程序的目录结构。您将看到这样的应用程序结构

因此,我们必须更改index.html页面中的文件引用。

    <link href="client/assets/css/main.css" rel="stylesheet" />
    <link href="client/assets/css/menu.css" rel="stylesheet" />
    
    <!-- external libs -->
    <script type="text/javascript" 
    src="client/assets/libs/angular.js"></script>
    <script type="text/javascript" 
    src="client/assets/libs/angular-route.js"></script>
    
    <!-- root -->
    <script src="client/ap/app.module.js"></script>
    <script src="client/ap/app.routes.js"></script>

    <!-- services -->
    <script src="client/ap/services/productFactory.js"></script>
    <script src="client/ap/services/categoryFactory.js"></script>

    <!-- controllers -->
    <script src="client/ap/controllers/productController.js"></script>
    <script src="client/ap/controllers/categoryController.js"></script>

    <!-- app -->
    <script src="client/ap/app.js"></script>

数据库

由于我们这篇帖子中使用的是SQL Compact Edition,让我们创建两个表ProductCategory,并使用以下模式填充示例数据。

ASP.NET-WebAPI

我们已经有了数据库,现在我们将开发WebAPI来与服务器通信。您可能已经注意到,我正在使用ASP.NET网站模板。因此,我们只需要编写数据访问代码并添加API控制器。在这里,我们需要做三件事

  1. 为我们的数据库创建Entity Framework模型。
  2. 创建两个视图模型类,ProductViewCategoryView
  3. 现在我们可以转到实际的WebAPI部分,创建两个控制器 - ProductControllerCategoryController

您将在附加的源代码中找到控制器和其他所有内容的代码,查看此代码列表,您需要将其放入Global.asax中以启用WebAPI路由。

	protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.MapHttpRoute(
                    name: "ActionApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
        }

现在我们的WebAPI已准备好被任何客户端调用。

JavaScript / Angular 工厂

由于我们在上一篇文章中使用了Angular工厂,我们只需要更改调用服务器数据的部分。现在,我们不再使用产品的或类别的内存数组,而是调用WebAPI从服务器端获取数据。以下是productFactory的更新代码列表。

// Define Factory
demoApp.factory('productFactory', function ($http) {
    var products = [];
    var categories = [];

    var factory = {};
    factory.getProducts = function () {

        $http.get('api/Product/Get').
            success(function (data, status, headers, config) {
                
                data = data.substring(1, data.length);
                data = data.substring(0, data.length - 1);
                data = data.replace(/\\/g, "");

                var jsonStringFormatted = data;
                
                var objectArray = JSON.parse(jsonStringFormatted);
                var obj;

                products.length = 0;
                for (i = 0; i < objectArray.length; i++) {

                    obj = factory.cloneProduct(objectArray[i]);
                    products.push(obj);
                }
                console.log("get products list - success");
            }).
            error(function (data, status, headers, config) {
                // log error
                console.log(status);
            });

        return products;
    };

    factory.getCategories = function () {

        $http.get('api/Category/Get').
            success(function (data, status, headers, config) {

                data = data.substring(1, data.length);
                data = data.substring(0, data.length - 1);
                data = data.replace(/\\/g, "");

                var jsonStringFormatted = data;

                var objectArray = JSON.parse(jsonStringFormatted);
                var obj;

                categories.length = 0;
                for (i = 0; i < objectArray.length; i++) {

                    obj = factory.cloneCategory(objectArray[i]);
                    categories.push(obj);
                }
            }).
            error(function (data, status, headers, config) {
                // log error
                console.log(status);
            });

        return categories;
    };

    factory.loadProductById = function (id) {
        var objFound;

        for (var i = 0; i < products.length; i++) {
            if (products[i].Id == id) {
                objFound = products[i];
                break;
            }
        }

        return objFound;
    };

    factory.getCategoryById = function (id) {
        var objFound;

        for (var i = 0; i < categories.length; i++) {
            if (categories[i].Id == id) {
                objFound = categories[i];
                break;
            }
        }

        return objFound;
    }

    factory.saveProduct = function (product) {
        
        var config = {
            //headers: 'application/x-www-form-urlencoded',
            headers: { 'Content-Type': 'application/json' }
        }

        $http.post('api/Product/PostProduct', product, config)
            .then(
                function (response, status, headers, config) {
                    console.log('PostProduct success: ' + product.Id); 
                },
                function (response, status, headers, config) {
                    console.log('PostProduct failed.', response, status, headers); 
                }
            );
    };

    factory.cloneProduct = function (obj) {

        tempObj = {};
        tempObj.Id = obj.Id;
        tempObj.ProductCode = obj.ProductCode;
        tempObj.ProductName = obj.ProductName;
        tempObj.Description = obj.Description;
        tempObj.CategoryID = obj.CategoryID;
        tempObj.CategoryName = obj.CategoryName;

        return tempObj;
    };

    factory.cloneCategory = function (obj) {

        tempObj = {};
        tempObj.Id = obj.Id;
        tempObj.CategoryCode = obj.CategoryCode;
        tempObj.CategoryName = obj.CategoryName;

        return tempObj;
    };

    factory.deleteProduct = function (id) {

        var params = "productID=" + id;

        $http.delete('api/Product/DeleteProduct?' + params)
        .then(
            function (response, status, headers) {
                console.log('DeleteProduct success: ');
            },
            function (response, status, headers) {
                console.log('DeleteProduct failed.', response, status, headers);
            }
        );
    };

    return factory;
});

在这里,您可以看到getProduts()函数通过调用$http.get('api/Product/Get')函数向WebAPI的ProductController发出HTTP GET请求。$hhtp.get()将接受两个回调函数:成功回调和错误回调,您可以为其编写所需的适当代码处理。类似地,我们使用了$hhtp.post()$hhtp.delete()分别用于发布和删除产品。

关注点

我们已经完成了使用服务器端数据存储的AngularJS CRUD示例。我只讨论了与一个实体Product相关的代码部分,对于Category,您也可以在下载的示例中找到类似的代码列表。

我在撰写本文时遇到了一件事,您可能也会觉得很有趣。在我使用旧版本的SQL Compact Edition (3.5.8080.0) 并用该版本创建我的数据库文件,并使用更高版本的Framework 4编写我的C#代码之前。当我尝试从该文件中访问数据时,我遇到一个错误,我通过简单地调用辅助类的SqlCeEngine.Upgrade()方法解决了这个问题。我没有从代码列表中删除它,您会发现这两行代码在ProductControllerGetAll方法中被注释掉了。

我希望您也喜欢这篇文章并从中获得了一些收获。我感谢您的反馈/评论或您想在此主题中提出的任何改进建议,以帮助使文章更好并对他人有所帮助。

历史

  • 2015年10月27日:发布
© . All rights reserved.