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

AngularJS 后端解决方案:ng-grid 与简单 REST API

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2014年10月8日

CPOL

6分钟阅读

viewsIcon

74389

使用 AngularJS 和 REST 对 ng-grid 进行筛选、排序和分页

引言

任何项目都普遍要求以某种表格形式显示数据。最简单的方法是使用 HTML 表格。但很快,这会变得复杂,因为您需要一种方式来支持分页(客户端和服务器端)、排序(单列和多列)、可调整大小的列、行内编辑、筛选等。本文/代码片段的作用、其有用性、它解决的问题等。

Using the Code

第一个网格解决方案

我们将要看的第一个解决方案是 `ng-grid`,它专为 AngularJS 构建,是 Angular 中最流行的网格解决方案。

从何开始

在这个项目中,我们将使用 Angular 和 `ng-grid` 构建一个网格解决方案,它通过 NodeJS 和 ExpressJS 钩入本地运行的 RESTful 端点。我们将使用 Node 和 Express 的基本功能。在深入探讨之前,您可能希望在 Plunker 上查看工作代码:http://embed.plnkr.co

假设

  1. 您已经了解 AngularJS
  2. 了解 Grunt、Bower 和 Bootstrap 的基础知识
  3. 对 REST 有基本了解
  4. 您的开发机器上已经安装了 node、npm、git 和 bower

项目结构

我们将使用以下 Angular 种子项目
https://github.com/libertyleap/angular-grunt-seed

这是一个种子项目,它带有用于 lint、karma、watch、livereload、express 服务器等的默认 bower 和 grunt 构建。

设置和运行种子项目的步骤

  1. 克隆项目

    > git clone https://github.com/backand/ng-grid-rest-simple-demo

  2. 将项目从 `angular-grunt-seed` 重命名为 `ng-grid-demo`

    > mv angular-grunt-seed ng-grid-demo

  3. 将当前目录更改为 *ng-grid-demo*

    > cd ng-grid-demo

  4. 执行 `npm install`,以便下载所有 Grunt 依赖项,它还会运行 bower install

    > npm install

  5. 执行 `grunt`,这将启动端口 9000 上的本地 Node 服务器

    > grunt

  6. 打开您喜欢的浏览器并访问:https://:9000/

使用 Bower 将 NG-Grid 添加到种子项目

将 `ng-grid` 添加到种子项目最简单的方法是使用 Bower,我们将在本博客中介绍这种方法。如果您不习惯这样做,您可以手动操作,即,访问 `ng-grid` 仓库:http://angular-ui.github.io/ng-grid/ 并复制下面介绍的所需文件。

> bower install ng-grid –save-dev

以上命令更新了 *ng-grid-demo\bower.json* 文件,添加了 `ng-grid` 作为依赖项。

"devDependencies": {

    "ng-grid": "~2.0.12"
}

Bower 将在本地下载 `ng-grid`。您可以通过进入 *bower-components* 文件夹进行验证。您将在 *bower-components* 文件夹中看到一个名为 *ng-grid* 的新文件夹。

将 NG-Grid 与视图 RESTful 服务连接

要在我们的种子项目中使用 `ng-grid`,我们需要引用两个 `ng-grid` 文件。第一个是 JavaScript 文件,第二个是用于网格主题的 CSS 文件。第一步是进入您的 *index.html* 文件,并将 JavaScript 和 CSS 文件都添加为依赖项。

打开 *ng-grid-demo/src/index.html* 文件并添加以下条目

  1. 在 `<head>` 中,添加此 CSS 依赖项 (*bower-components/ng-grid/ng-grid.css*)。

  2. 在 `<body>` 部分,添加 `ng-grid` 的 js 依赖项 (*bower-components/ng-grid/ng-grid-2.0.12.debug.js*)。
  3. 我们需要将“`ngGrid`”Angular 模块依赖项添加到 *app.js*,以便我们可以开始使用 `ng-grid` 的指令和其他服务。

NG-Grid 基本示例

在本节中,我们将介绍添加基本 `ng-grid` 示例所需的步骤。我们将在接下来的部分中探索 `ng-grid` 的高级功能。

为了演示网格功能,我们需要某种 REST 端点。对于这篇博客文章,我们将使用本地 JSON 文件作为 REST 端点,它将提供开源贡献者列表。

REST \ JSON

在 *ng-grid-demo\src* 文件夹下创建一个 *json* 文件夹。创建一个名为 *contributors.json* 的新 json 文件。此 JSON 文件将包含以下内容,这些内容将提供给 UI * \ ng-grid*。

ng-grid-demo\src\json\contributor.json
[{
    "id": "1",
    "firstname": "Misko",
    "lastname": "Havery",
    "company": "Google",
    "project": "AngularJS"
}, {
    "id": "2",
    "firstname": "Srini",
    "lastname": "Kusunam",
    "company": "LibertyLeap",
    "project": "Backbone.Paginator"
}, {
    "id": "3",
    "firstname": "Derick",
    "lastname": "Bailey",
    "company": "Muted Solutions",
    "project": "Backbone.Marionette"
}]

更改 Grunt 构建,将此 json 文件包含在 *.build* 目录中。

Angular Factory

让我们创建一个服务 (*gridService.js*),它将使用 REST 的 `GET` 方法返回上述 JSON。这些数据将异步返回,我们将为此使用 Promise (`$q`)。这是服务代码。

angular.module('angularGruntSeed')
    .factory('GridService', ['$http', '$q',
        function($http, $q) {
            var contributorsFile = 'json/contributors.json';
            var contributors = [];
 
            function getContributors() {
                var deferred = $q.defer();
 
                $http.get(contributorsFile)
                    .then(function(result) {
                        contributors = result.data;
                        deferred.resolve(contributors);
                    }, function(error) {
                        deferred.reject(error);
                    });
 
                return deferred.promise;
            }

            return {
                getContributors: getContributors
            };
        }
    ]);

我们将有一个名为 `getContributors` 的方法,它将使用 Angular 的 `$http` (https://docs.angularjs.org/api/ng/service/$http) 从 *json/contributors.json* 文件获取数据。它还使用了 Angular 的 promise 实现 `$q` (https://docs.angularjs.org/api/ng/service/$q)。

这是这里发生的事情

  • 当控制器调用此工厂方法“`getContributors`”时,它将获得一个 promise 对象,即 `deferred.promise`。
  • 当异步 `$http` 调用返回响应时,我们将解析延迟对象以返回贡献者列表。
  • 如果 `$http` 中出现错误,那么我们将拒绝带有原因的延迟对象,以便调用者可以适当地处理它,即向用户显示某种消息。

控制器 (Controller)

我们将“`GridService`”添加为“`HomeController`”的依赖项,并从 `GridService` 调用“`getContributors`”方法。响应被设置为“`myData`”,它将用于在视图中填充 `ng-grid` 数据。

angular.module('angularGruntSeed')
.controller('HomeController', ['$scope', 'GridService',
    function($scope, gridService) {
         gridService.getContributors().then(function(data) {
            $scope.myData = data;
        });
 
        $scope.gridOptions = {
            data: 'myData'
        };
    }
]);

上述步骤 `$scope.gridOptions` 是主要设置,它将 `ng-grid` 配置连接到 `ng-grid` 的视图。

视图

在 HTML 文件中设置网格非常简单,只需创建一个 `div`,并向其中添加 `ng-grid` 指令,参数是我们将很快创建的控制器中的函数。我们还将向 `div` 添加一个简单的类以便于样式设置。更改“templates\home.html”以包含以下代码

<div class="gridStyle" ng-grid="gridOptions"></div> 

在这里,“`gridOptions`”是控制器中填充的 `$scope` 对象。

这应该能让基本的 `ng-grid` 运行起来。

NG-Grid 功能

在本节中,我们将探讨 `ng-grid` 的不同配置选项。我们只需要更改 `Controller` 中的 `$scope.gridOptions` 即可支持以下功能。

列定义

任何 `Grid` 都普遍要求列名与 JSON 名称不同。上面的一个例子是我们将“`firstname`”命名为“`First Name`”。

$scope.gridOptions = {
    data: 'myData',
    // Column definition example
    columnDefs: [{field:'id'},{field:'firstname', displayName:'First Name'},     
                 {field:'lastname',displayName:'LastName'},{field:'company'},{field:'project'}]
};

单元格模板示例

以下是如何在 `ng-grid` 中使用 `string` 定义单元格模板的示例。在上面的示例中,我们希望将绿色应用于 `id` 大于 1 的 `id` 列。

$scope.gridOptions = {
    data: 'myData',
    columnDefs: [
{field:'id', cellTemplate: '
<div ng-class="{green: row.getProperty(col.field) > 1}">
			<div class="ngCellText">{{row.getProperty(col.field)}}</div>
			</div>
'}, {field:'firstname', displayName:'First Name'}, 
{field:'lastname', displayName:'Last Name'}, 
{field:'company'},{field:'project'}] };

行内单元格编辑示例

我们将探讨一个选项,能够编辑 `Grid` 单元格并将其保存到 REST 服务。我们将演示代码,以便能够更新 `Grid` 中贡献者的“`company`”单元格。

homeController.js

我们需要将列定义中的 `enableCellEdit` 属性设置为 `TRUE`。

            {
                field:'company',
                enableCellEdit: true
            }					

设置此项后,如果您重新启动 `node` 服务器,您将看到双击单元格后 `company` 列变为可编辑。

下一步是我们将此更新的单元格信息发送到 REST 后端。为此,我们将使用 `ng-grid` 的一个 `Event` (`ngGridEventEndCellEdit`),它将在单元格编辑后广播。您可以在此处查看所有可用的 `ng-grid` `Event`:https://github.com/angular-ui/ng-grid/wiki/Grid-Events

我们将更新控制器以包含以下代码

$scope.$on('ngGridEventEndCellEdit', function(evt){
   // Detect changes and send entity to REST server
   gridService.saveContributor(evt.targetScope.row.entity);
});

从上面的代码中可以看出,我们希望将更新的行信息发送回 REST 服务。我们需要在我们的 *gridService.js* 中定义一个新方法 `saveContributor`。

gridService.js

function saveContributor(contributor) {
    $http.post('/save', contributor).success(function() {
    console.log("SAVE success !!!!");
    }).error(function() {
    console.log("SAVE Error !!!!");
    });
}

我们没有真正的 REST 服务,而且由于我们需要某种持久存储,因此不可能演示这一点。您可以打开浏览器的开发人员工具并验证上述 `$http post` 方法是否已使用正确的数据调用。

参考文献

© . All rights reserved.