Simple AngularJS Front-End for a REST API – 用于REST API的简单AngularJS前端

最后修改: 2015年 10月 20日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial we’ll learn how to consume a RESTful API from an simple AngularJS front-end.

在这个快速教程中,我们将学习如何从一个简单的AngularJS前端消费一个RESTful API。

We’re going to display data in a table, create a resource, update it, and finally delete it.

我们将在一个表中显示数据,创建一个资源,更新它,最后删除它。

2. The REST API

2.REST API

First, let’s take a quick look at our simple API – exposing a Feed resource with pagination:

首先,让我们快速看一下我们的简单API–暴露一个带分页的Feed资源。

  • get paginated – GET /api/myFeeds?page={page}&size={size}&sortDir={dir}&sort={propertyName}
  • create – POST /api/myFeeds
  • update – PUT /api/myFeeds/{id}
  • delete – DELETE /api/myFeeds/{id}

A quick note here is that pagination is using the following 4 parameters:

这里要说明的是,分页是使用以下4个参数。

  • page: index of requested page
  • size: maximum number of records per page
  • sort: the name of property used in sorting
  • sortDir: the sorting direction

And here’s an example of what the Feed resource looks like:

这里有一个Feed资源的例子。

{
    "id":1,
    "name":"baeldung feed",
    "url":"/feed"
}

3. The Feeds Page

3.饲料页

Now, lets take a look at our feeds page:

现在,让我们来看看我们的馈赠页面。

<script 
  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js">
</script>
<script 
  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-resource.min.js">
</script>
<script th:src="@{/resources/ng-table.min.js}"></script>
<script th:src="@{/resources/mainCtrl.js}"></script>

<a href="#" ng-click="addNewFeed()">Add New RSS Feed</a>
<table ng-table="tableParams">
    <tr ng-repeat="row in $data track by row.id">
        <td data-title="'Name'" sortable="'name'">{{row.name}}</td>
        <td data-title="'Feed URL'" sortable="'url'">{{row.url}}</td>
        <td data-title="'Actions'">
            <a href="#" ng-click="editFeed(row) ">Edit</a>
            <a href="#" ng-click="confirmDelete(row.id) ">Delete</a>
        </td>
    </tr>
</table>
</div>
</body>
</html>

Note that we used ng-table to display data – more on that in the following sections.

请注意,我们使用ng-table来显示数据–在下面的章节中会有更多的介绍。

4. An Angular Controller

4.一个Angular控制器

Next, let’s have a look at our AngularJS controller:

接下来,让我们看一下我们的AngularJS控制器。

var app = angular.module('myApp', ["ngTable", "ngResource"]);
app.controller('mainCtrl', function($scope, NgTableParams, $resource) {
    ...   
});

Note that:

请注意,。

  • We injected the ngTable module to use it for displaying our data in a user friendly table and handle pagination/sorting operations
  • We also injected ngResource module to use it for accessing our REST API resources

5. An AngularJS DataTable

5.一个AngularJS DataTable

Let’s now have a quick look at the ng-table module – here’s the configuration:

现在让我们快速浏览一下ng-table模块–这里是配置。

$scope.feed = $resource("api/myFeeds/:feedId",{feedId:'@id'});
$scope.tableParams = new NgTableParams({}, {
    getData: function(params) {
        var queryParams = {
            page:params.page() - 1, 
            size:params.count()
        };
        var sortingProp = Object.keys(params.sorting());
        if(sortingProp.length == 1){
    	    queryParams["sort"] = sortingProp[0];
    	    queryParams["sortDir"] = params.sorting()[sortingProp[0]];
        }
        return $scope.feed.query(queryParams, function(data, headers) {
            var totalRecords = headers("PAGING_INFO").split(",")[0].split("=")[1];
            params.total(totalRecords);
            return data;
        }).$promise;
    }
});

The API expects a certain style of pagination, so we need to customize that here in the table to match it. We’re using params out of ng-module and creat our own queryParams here.

API期望有某种风格的分页,所以我们需要在表格中自定义,以匹配它。我们使用paramsng-module,并在这里创建我们自己的queryParams

A few additional notes about pagination:

关于分页的一些补充说明。

  • params.page() starts from 1 so we also need to make sure it becomes zero indexed when communicating with the API
  • params.sorting() returns an object – for example {“name”: “asc”}, so we need to separate the key and value as two different parameters – sort, sortDir
  • we extract the total element count from a HTTP header of the Response

6. More Operations

6.更多的业务

Finally, we can perform a lot of operations using ngResource module – $resource does cover the full HTTP semantics in terms of available operations. We can also define our custom functionality.

最后,我们可以使用ngResource模块进行大量的操作–$resource在可用操作方面确实涵盖了完整的HTTP语义。我们还可以定义我们的自定义功能。

We have used query in the previous section to get the feeds list. Note that both get and query do GET – but query is used to handle an array response.

我们在上一节使用了query来获取feeds列表。请注意,getquery都是做GET – 但query是用来处理一个数组响应的。

6.1. Add a New Feed

6.1.添加一个新的Feed

In order to add new feed we will use $resource method save – as follows:

为了添加新的饲料,我们将使用$resource方法save – 如下所示。

$scope.feed = {name:"New feed", url: "http://www.example.com/feed"};

$scope.createFeed = function(){
    $scope.feeds.save($scope.feed, function(){
        $scope.tableParams.reload();
    });
}

6.2. Update a Feed

6.2.更新一个Feed

We can use our own custom method with $resource – as follows:

我们可以使用我们自己的自定义方法与$resource – 如下所示。

$scope.feeds = $resource("api/myFeeds/:feedId",{feedId:'@id'},{
    'update': { method:'PUT' }
});

$scope.updateFeed = function(){
    $scope.feeds.update($scope.feed, function(){
        $scope.tableParams.reload();
    });
}

Note how we configured our own update method to send out a PUT request.

注意我们是如何配置自己的update方法来发送PUT请求的。

6.3. Delete a Feed

6.3.删除一个饲料

Finally, we can delete a feed by using delete method:

最后,我们可以通过使用delete方法删除一个饲料。

$scope.confirmDelete = function(id){
    $scope.feeds.delete({feedId:id}, function(){
        $scope.tableParams.reload();
    });
}

7. AngularJs Dialog

7.AngularJs对话框

Now, let’s see how to use ngDialog module to display simple form for adding/updating our feeds.

现在,让我们看看如何使用ngDialog模块来显示用于添加/更新饲料的简单表单。

Here is our template, we can define it in a separate HTML page or in the same page:

这里是我们的模板,我们可以在一个单独的HTML页面或在同一个页面中定义它。

<script type="text/ng-template" id="templateId">
<div class="ngdialog-message">
    <h2>{{feed.name}}</h2>
    <input ng-model="feed.name"/>
    <input ng-model="feed.url"/>
</div>
<div class="ngdialog-buttons mt">
    <button ng-click="save()">Save</button>
</div>
</script>

And then we will open our dialog to add/edit a feed:

然后,我们将打开我们的对话框,添加/编辑一个饲料。

$scope.addNewFeed = function(){
    $scope.feed = {name:"New Feed", url: ""};
    ngDialog.open({ template: 'templateId', scope: $scope});
}
$scope.editFeed = function(row){
    $scope.feed.id = row.id;
    $scope.feed.name = row.name;
    $scope.feed.url = row.url;
    ngDialog.open({ template: 'templateId', scope: $scope});
}
$scope.save = function(){
    ngDialog.close('ngdialog1');
    if(! $scope.feed.id){
        $scope.createFeed();
    } else{
        $scope.updateFeed();
    }
}

Note that:

请注意,。

  • $scope.save() is called when user clicks Save button in our dialog
  • $scope.addNewFeed() is called when user clicks Add New Feed button in feeds page – it initializes a new Feed object (without id)
  • $scope.editFeed() is called when user wants to edit a specific row in Feeds table

8. Error Handling

8.错误处理

Finally, let’s see how to handle response error messages using AngularJS.

最后,让我们看看如何使用AngularJS处理响应错误信息

In order to handle server error responses globally – instead of per request – we’ll register an interceptor to the $httpProvider:

为了全局地处理服务器错误响应–而不是每个请求–我们将向$httpProvider注册一个拦截程序。

app.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push(function ($q,$rootScope) {
        return {
            'responseError': function (responseError) {
                $rootScope.message = responseError.data.message;
                return $q.reject(responseError);
            }
        };
    });
}]);

And here’s our message representation in HTML:

这里是我们的HTML信息表述。

<div ng-show="message" class="alert alert-danger">
    {{message}}
</div>

9. Conclusion

9.结论

This was a quick writeup of consuming a REST API from AngularJS.

这是一篇关于从AngularJS消费REST API的快速写作。

The full implementation of this tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

本教程的完整实现可以在github项目中找到 – 这是一个基于Eclipse的项目,因此应该很容易导入并按原样运行。