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

SharePoint REST API 和 AngularJs (适用于 2013, 2016 和 Online)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (5投票s)

2016 年 7 月 29 日

CPOL

5分钟阅读

viewsIcon

41620

downloadIcon

648

SharePoint 和 AngularJs 以及 HTTP 请求,例如 GET, POST, UPDATE, DELETE 和使用 AngularJS 进行文件上传

引言

此示例包含一个可重用的 angularjs 模块。该模块包含一个服务和一个指令。任何人都可以通过依赖注入使用此模块。这适用于希望利用 SharePoint 客户端开发中双向数据绑定的用户。在客户端开发中,我们基本上会向一些特定的端点发出 GET, POST, UPDATEDELETE 请求。因此,此模块将为您节省编写任何 HTTP 请求的代码冗余。该模块适用于内容编辑器 Web 部件和 SharePoint 托管应用开发。

开始之前

目标用户在使用此模块之前需要具备以下知识。我将在下面提供一些相关内容的参考。

  1. AngularJs
  2. REST API 和 SharePoint 列表
  3. SharePoint 和 AngularJs

当前问题

获取所有列表的典型 GET 请求如下所示:

function getAllLists() {
    $http({
        url: "/_api/web/lists"
            method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-Type": "application/json;odata=verbose"
        }
    }).success(function(result) {
        //do something here
    }).error(function(error, status) {
        // do something here
    });
}

而获取特定列表所有项目的 GET 请求如下所示:

function getAllItems() {
    $http({
        url: "/_api/web/lists/GetByTitle('List Title')/Items"
            method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-Type": "application/json;odata=verbose"
        }
    }).success(function(result) {
        //do something here
    }).error(function(error, status) {
        // do something here
    });
}

这些函数的作用不同,但它们共享大部分代码。因此,该模块负责处理 GET, POST, UPDATEDELETE 请求的所有繁琐工作。您只需传递您的 dataurl 即可发出任何类型的请求。此模块的源代码如下所示:

(function() {
    'use strict';

    angular.module('spNgModule', []).factory
    ("spBaseService", spBaseService).directive("customFileChange", customFileChange);;

    spBaseService.$inject = ["$q", "$http", "IS_APP_WEB"];

    function spBaseService($q, $http, isAppWeb) {

        var baseUrl = isAppWeb ? _spPageContextInfo.webAbsoluteUrl : 
                                 _spPageContextInfo.siteAbsoluteUrl;

        return {
            getRequest: getRequest,
            postRequest: postRequest,
            updateRequest: updateRequest,
            deleteRequest: deleteRequest,
            fileUploadRequest: fileUploadRequest,
            baseUrl: baseUrl
        };

        function getRequest(query, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + query,
                method: "GET",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "content-Type": "application/json;odata=verbose"
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function postRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "POST",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "content-Type": "application/json;odata=verbose"
                },
                data: JSON.stringify(data)
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function fileUploadRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "POST",
                processData: false,
                data: data,
                transformRequest: angular.identity,
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "Content-Type": undefined
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function updateRequest(data, url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "PATCH",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "content-Type": "application/json;odata=verbose",
                    "X-Http-Method": "PATCH",
                    "If-Match": "*"
                },
                data: JSON.stringify(data)
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }

        function deleteRequest(url, endPoint) {
            var deferred = $q.defer();
            $http({
                url: endPoint || baseUrl + url,
                method: "DELETE",
                headers: {
                    "accept": "application/json;odata=verbose",
                    "X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
                    "IF-MATCH": "*"
                }
            }).success(function(result) {
                deferred.resolve(result);
            }).error(function(result, status) {
                deferred.reject({
                    error: result,
                    status: status
                });
            });
            return deferred.promise;
        }
    }

    customFileChange.$inject = ["$parse"];

    function customFileChange($parse) {
        return {
            restrict: "A",
            link: function(scope, element, attrs) {
                var model = $parse(attrs.customFileChange);
                var modelSetter = model.assign;
                element.bind("change", function() {
                    scope.$apply(function() {
                        var reader = new FileReader();
                        reader.onload = function(e) {
                            var fileModel = {
                                fileName: element[0].files[0].name,
                                fileAsBuffer: e.target.result
                            };
                            modelSetter(scope, fileModel);
                        }
                        reader.onerror = function(e) {
                            alert(e.target.error);
                        }
                        reader.readAsArrayBuffer(element[0].files[0]);
                    });
                });
            }
        };
    }

})(window, document);

此模块包含的内容

  • getRequest(query, endPoint)
  • postRequest(data, url, endPoint)
  • updateRequest(data, url, endPoint)
  • deleteRequest(url, endPoint)
  • fileUploadRequest(data, url, endPoint)

endPoint 在所有地方都是可选的。稍后将讨论其用法。您将能够使用支持 GET, POST, UPDATEDELETE 请求的这些端点。每个方法都会返回一个 Promise,您需要在代码中对其进行处理。

如何使用

首先,从附件下载此模块。附件包含我的模块的最小化和非最小化版本。下载文件后,请在您的项目中添加引用。例如,在 SharePoint 托管应用中,应如下所示:

<script src="../Scripts/App/spNgModule.js"></script>

在内容编辑器 Web 部件中,您需要将此文件上传到某个库,然后才能使用它。

在模块中添加依赖

您可以通过以下方式将此依赖项添加到您的模块中。此模块的名称是 spNgModule

(function () {
    angular.module("spNgModuleTest", ["spNgModule"])
    .constant("IS_APP_WEB", false);
})();

在这里,您需要指定 IS_APP_WEB 的值。这意味着将使用哪个 Web URL 来发出 GET, POST, UPDATEDELETE 请求。在指定 IS_APP_WEB 的值之后,您还可以使用其他 URL 来发出任何请求。这就是为什么有一个名为 endPoint 的可选参数。

注意:如果您在请求中指定了 endPoint,那么 url 参数将是可选的。默认情况下,所有请求都将基于 IS_APP_WEB 的值发出。无论是 APP Web 还是 Host Web。

注入服务

我使用的服务名称是 spBaseService。因此,您可以按以下方式注入此服务:

angular.module("spNgModuleTest")
    .factory("spNgTestSvc", spNgTestSvc);

    spNgTestSvc.$inject = ["spBaseService"];

GET 请求示例

spBaseService.getRequest(query, endPoint)

您可以传递支持 HTTP GET 请求的任何查询或端点。例如:

您想获取当前站点下的所有列表

function getAllLists() {
    var query = "/_api/web/lists?$select=Title";
    return spBaseService.getRequest(query);
}

如果您想获取列表的所有项目,那么将是:

function getAllItems() {
    var query = "/_api/web/lists/GetByTitle('List Title')/Items";
    return spBaseService.getRequest(query);
}

如果您想获取所有子站点,那么将是:

function getSubSites() {
    var query = "/_api/Web/Webs";
    return spBaseService.getRequest(query);
}

所以,我通过这些示例想说的是:只需发出任何 GET 请求,您就需要处理查询或端点。

endPoint 参数的使用

有些人可能需要在以下场景中使用 endPoint

假设您当前的站点是 https://xxx.sharepoint.com (可以是 Host Web 或 App Web)。现在您想对子站点 https://xxx.sharepoint.com/hr 发出 GET, POST, UPDATEDELETE 请求,或者从 App Web 对 Host Web 发出 GET, POST, UPDATEDELETE 请求。在这种情况下,您需要使用 endPoint

function getSubSites() {
    var endPoint = "https://xxx.sharepoint.com/hr/_api/Web/Webs";
    return spBaseService.getRequest(null, endPoint);
}

POST 请求示例

这适用于添加新对象(列表项、文件、站点、文档等)。

spBaseService.postRequest(data, url, endPoint)

data 是请求体。它会因请求而异。例如,要添加一个子站点,请求体应如下所示:

var data = {
    parameters: {
        __metadata: {
            'type': 'SP.WebInfoCreationInformation'
        },
        Url: "site url",
        Title: "site title",
        Description: "site description",
        Language: 1033,
        UseUniquePermissions: true
    }
};

url 是任何支持 POST 请求的端点。要添加子站点,端点是:

var url = "/_api/web/webinfos/add";

endPoint 的用法可以在 此处 找到。

因此,添加站点的完整 POST 请求是:

function addSubSite() {
    var data = {
        parameters: {
            __metadata: {
                'type': 'SP.WebInfoCreationInformation'
            },
            Url: "site url",
            Title: "site title",
            Description: "site description",
            Language: 1033,
            UseUniquePermissions: true
        }
    };
    var url = "/_api/web/webinfos/add";
    return spBaseService.postRequest(data, url);
}

UPDATE 请求示例

spBaseService.updateRequest(data, url, endPoint);

它与 POST 请求几乎相同。您可以使用此方法更新站点中的任何对象。看看更新特定列表中的项目。

function updateItemById(itemId) {
    var url = "/_api/web/lists/GetByTitle('List Name')/GetItemById(" + itemId + ")";

    var data = {
        __metadata: {
            type: "SP.Data.SpNgListListItem"
        },
        Title: "New sp ng item updated " + Math.random()
    };
    return spBaseService.updateRequest(data, url);
}

请在此处 查看 endPoint 的用法。

DELETE 请求示例

spBaseService.deleteRequest(url, endPoint);

您将使用此方法从站点中删除某些内容。假设我们要删除 ID 等于 5 的项目。

function deleteAnItem() {
    var url = "/_api/web/lists/GetByTitle('List Name')/GetItemById(5)";
    return spBaseService.deleteRequest(url);
}

请在此处 查看 endPoint 的用法。

文件上传示例

spBaseService.fileUploadRequest(data, url, endPoint);

在请求体中,您需要将文件作为 ArrayBuffer 传递。如前所述,此模块还包含一个指令,该指令将帮助您以 ArrayBuffer 格式获取文件。该指令的名称是 customFileChange。用于上传的 HTML 应如下所示:

<input type="file" data-custom-file-change="attachment" /> 

attachment 是模型,它将为您提供 ArrayBuffer 格式的文件。您可以根据需要更改其名称。您将从此模型中获得两个属性,例如 fileNamefileAsBuffer

以下是上传 ID 等于 2 的特定项目的附件的示例:

function uploadAttachment(attachment){
            var url = "/_api/web/lists/GetByTitle('SpNgList')/items(2)/
                       AttachmentFiles/add(FileName='" + attachment.fileName + "')";
            return spBaseService.fileUploadRequest(attachment.fileAsBuffer, url);
        }

请在此处 查看 endPoint 的用法。

处理响应示例

您将从上述所有方法中获得一个 Promise 作为返回值。因此,这与典型的响应处理 Angular 代码相同。例如:

spNgTestSvc.addSubSite()
    .then(function(successResponse) {
        // code after success
    }, function(errorrResponse) {
        //code after error
    });

errorResponse 有两个属性,例如 errorstatuserror 是 SharePoint 端点返回的实际错误对象。

结论

以上就是我当前模块的全部内容。我将尝试在未来的更新中使其变得更好。由于我的源代码是开放的,如果您能收到读者的任何反馈和建议,我将非常高兴。

历史

  • 2016 年 7 月 29 日:初始版本
© . All rights reserved.