AngularJS ngResource 教程
在本教程中,我将讨论 ngResource 的工作原理。我将演示所有 4 种 HTTP 动词(或方法),以及请求输入数据可以打包的多种方式。这将是一个非常有趣的教程。
引言
这很重要。至少对我来说。当我第一次学习 AngularJS 时,有几件事我觉得非常困难。它们是:
- 将所有模块和组件链接到一个应用程序的依赖注入概念
- 过滤以及如何创建自定义过滤器
- 指令,有很多种创建方式。以及独立作用域的概念。要理解这两者是如何工作的,有点难。
- ngIf 及其创建的子作用域
- 以及许多以神秘方式破坏应用程序的杂项
主要问题是 AngularJS 的语法。它与 Java 和 C# 等传统语言有很大不同。一旦我理解了如何绕过这些问题,就好像揭开了这项技术上一层面纱,一切都变得清晰了。那时我就可以轻松地使用这项技术了。关键在于阅读文档,以及阅读其他人的教程。然后进行大量实验,学习语法。最终,阅读 AngularJS 代码变得容易,一切也都变得容易了。本教程是我如何使用 ngResource 组件的总结。
在 AngularJS 应用程序中,应用程序与后端 Web 服务之间的任何数据交换都通过 RESTFul API 调用进行处理。也就是说,交换是通过 HTTP Get、HTTP Post、HTTP Put 和 HTTP Delete 请求来处理的。请求可以通过 URL 路径、请求参数、JSON 或 x-www-url-encoded 请求 string 来打包输入参数。本教程将探讨所有这些。本文不涵盖基于表单的多部分文件上传。文件上传将在另一篇教程中讨论。在我们开始实际讨论之前,我想先回顾一下示例项目的架构。
示例项目整体架构
本教程中包含的示例项目是基于 Spring Boot 的应用程序。Java 代码将创建一个 RESTFul 应用程序。在此应用程序的 resources 文件夹内,有一个名为“static”的子文件夹下的 index.html 页面,其中托管着用于练习我想要讨论的所有场景的 AngularJS 应用程序。
AngularJS 应用程序由两个文件组成,一个是“app.js”,它处理“index.html”页面上的用户交互;另一个文件是“sampleService.js”。第二个 JS 文件将提供调用 RESTFul 服务的服务功能。
“index.html”页面分为八个部分。每个部分都有两个按钮,“Test”按钮。点击时,处理点击的方法将调用服务对象(来自“sampleService.js”),该服务对象进而调用 ngResource 从 RESTFul API 获取数据。数据返回并成功处理后,页面将以 JSON 格式显示 API 调用 URL 和响应数据。另一个按钮“Reset”将清除所有变量并清理该部分。然后您可以再次运行该场景。
这是我刚才描述的测试部分的屏幕截图

这是点击“Test”按钮后测试部分的屏幕截图

ngResource 的基本用法
在本节中,我想向您展示如何使用 ngResource。第一步是将 ngResource 模块注入到应用程序模块或任何需要 ngResource 的模块中。这是执行此操作的代码:
"use strict";
var mod = angular.module("restSampleApp", [ "ngResource", "sampleServiceModule" ]);
这是另一个例子
"use strict";
var mod = angular.module("sampleServiceModule", [ "ngResource" ]);
在这两个示例中,我都创建了一个 AngularJS 模块,该模块依赖于其他可用模块。angular 中的 module 方法将第一个参数作为新创建模块的名称,第二个参数是所依赖模块名称的数组。ngResource 是 AngularJS 资源服务的模块,可用于从后端 RESTFul API 获取数据。第二个代码片段是一个很好的例子,新创建的模块只有一个依赖项,即 ngResource。
下一步是将名为 $resource 的对象注入到控制器/工厂/等中。以下是方法:
mod.controller("restSampleController", [ "$scope", "$resource", "sampleRestService",
  function ($scope, $resource, sampleRestService) {
     ...
  }
]);
之前,已通过 angular.module(...) 创建了一个名为 mod 的对象。使用此对象,我们可以定义一个控制器或其他内容,例如创建 service 对象的工厂。在上面的代码片段中,我们正在创建一个控制器。第一个参数是控制器的名称。下一个参数是一个数组,其中前几个元素是控制器所依赖对象的名称。控制器本身是一个函数,它将所有这些对象作为参数。在上面的代码片段中,控制器注入了三个不同的对象:"$scope"、"$resource" 和 "sampleRestService"。在控制器实际依赖的函数中,直接使用对象的名称作为参数。这是为了舒适地利用 AngularJS 必须掌握的概念之一。
总之,注入的对象之一称为 $resource。因为它是 AngularJS 框架的一部分,所以它有一个“$”前缀。我特意将 ngResource 对象注入到这个主控制器中,以便我可以演示 ngResource 的基本用法。
现在,是时候看看 ngResource 的最基本用法了。在“app.js”中,有一个作用域绑定的方法称为 vm.clickGetCar()。内部的代码逻辑显示了基本用法。这是代码:
vm.clickGetCar = function () {
   var restSvc = $resource("./getCar/:make/:year/:model", {
         make: "@make",
         year: "@year",
         model: "@model"
      }, {
      "getCar": {
         method: "get",
         isArray: false
      }
   });
   
   var prom = restSvc.getCar({
      make: "honda",
      year: 1997,
      model: "civic"
   }).$promise;
   
   prom.then(function (result) {
      if (result) {
         vm.getCarSucceeded = true;
         vm.getCarResponse = JSON.stringify(result, null, 3);
      } else {
         vm.getCarFailed = true;
         vm.getCarErrorMsg = "Error occurred.";                  
      }
   }, function(error) {
      vm.getCarFailed = true;
      vm.getCarErrorMsg = "Error occurred.";
   });
};
此方法分为三个独立的部分。第一部分通过调用 $resource 作为方法来定义一个 ngResource 对象。$resource 方法有三个输入参数:
- 第一个参数是一个 string,代表 REST API 的 URL 模式。在这种情况下,它是相对路径,并且路径中有三个参数,以“:”为前缀。例如,变量名“:make”表示路径的这一部分是汽车制造商的值。另外两个是汽车的年份和汽车的型号。
- 第二个参数是一个具有三个属性的对象。它用于定义输入值如何转换为 URL 路径的值。当使用 ngResource对象调用后端服务时,将传入制造商、型号和汽车年份等输入值。这些值将是发送为 HTTP 请求的 URL 的一部分。
- 最后一个参数是另一个对象,它为此 ngResource定义了一个操作。它定义了如何发送 HTTP 请求。在这种情况下,HTTP 请求应作为GET请求发送。当响应返回时,ngResource对象期望该对象只是一个对象,而不是对象数组。内部对象与一个名为“getCar”的键相关联,“getCar”将成为一个方法。您很快就会看到它的实际效果。
这是第一部分
var restSvc = $resource("./getCar/:make/:year/:model", {
      make: "@make",
      year: "@year",
      model: "@model"
   }, {
   "getCar": {
      method: "get",
      isArray: false
   }
});
第二部分是通过调用定义的动作方法 -- getCar() -- 来调用 ngResource 对象。调用将返回一个 promise。此部分与第一部分密切相关。第一部分使用 $resource() 并动态创建一个至少包含一个名为 getCar() 的方法。第二部分使用 ngResource 对象并调用其名为 getCar() 的方法。由于调用是 async 的,因此我们需要向其提供一个回调方法,以便在调用完成时,它使用自定义的回调方法来处理结果。这发生在第三部分。这是第二部分:
var prom = restSvc.getCar({
   make: "honda",
   year: 1997,
   model: "civic"
}).$promise;
一旦我们从异步调用中获得了 promise,我们就可以提供一个回调来处理返回的结果。promise 对象有一个名为 then() 的方法。它接受两个函数作为输入。第一个处理成功响应返回的情况。第二个处理错误响应。这是第三部分:
prom.then(function (result) {
   if (result) {
      vm.getCarSucceeded = true;
      vm.getCarResponse = JSON.stringify(result, null, 3);
   } else {
      vm.getCarFailed = true;
      vm.getCarErrorMsg = "Error occurred.";                  
   }
}, function(error) {
   vm.getCarFailed = true;
   vm.getCarErrorMsg = "Error occurred.";
});
如上所示,如果响应成功,返回的结果将是一个 JavaScript 对象。它要么是对象,要么是数组。在这种情况下,我们只期望一个对象。如果成功捕获该对象,它将被转换为 JSON 字符串。作用域绑定的变量 vm.getCarSucceeded 和 vm.getCarResponse 将存储结果。然后页面将显示响应对象。
HTML 页面如何显示结果
<div class="row">
   <div class="col-xs-12">
     <div class="panel panel-default">
        <div class="panel-heading">
           Rest Get
        </div>
        <div class="panel-body">
           <p>Get HTTP Request with Path Variables. Use ngResource directly.</p>
           <div ng-if="vm.getCarSucceeded">
           <p><strong>Request Url</strong></p>
<pre>
{{vm.getCarRequestUrl}}
</pre>                    
           <p><strong>Response</strong></p>
<pre>
{{vm.getCarResponse}}
</pre>
           </div>
           <div class="row" ng-if="vm.getCarFailed">
              <div class="col-xs-12">
                 <div class="alert alert-danger">{{vm.getCarErrorMsg}}</div>
              </div>
           </div>
           <button class="btn btn-primary" ng-click="vm.clickGetCar()">Test</button>
           <button class="btn btn-primary" ng-click="vm.resetGetCar()">Reset</button>
        </div>
     </div>
   </div>
</div>
在上面的 HTML 代码中,用于显示部分的 ng-if 使用 vm.getCarSucceeded 来控制是否显示响应对象。如果 vm.getCarSucceeded 设置为 true,它将显示请求的 URL 和 JSON 响应。如果请求处理因某种原因失败,则 div 中的 ng-if 使用 vm.getCarFailed 来控制是否显示。它将显示错误消息。
就是这样。无论它看起来多么简单或多么复杂,这都是 ngResource 可以用来处理前端和后端数据交换的方式。在下一节中,我将向您展示另一种使用 ngResource 的方法。
一个 ngResource 对象,多个操作
在上节中,我已经向您展示了使用 ngResource 定义一个具有单个请求 URL 和单个操作的对象的方法。我想用不同的方式使用 ngResource。而不是在 $resource() 的第一个和第二个参数中指定 URL 和输入参数,我会将它们设置为 null,并依赖操作作为单独的请求处理程序。看看 sampleService.js。$resource() 方法调用有多个操作,第一个和第二个参数默认为 null。
var restSvc = $resource(null, null, {
   "getCar": {
      url: "./getCar/:make/:year/:model",
      method: "get",
      isArray: false,
      params: {
         make: "@make",
         year: "@year",
         model: "@model"
      }
   },
   ...
});
此处显示的此代码片段与上一节中的代码功能相同。区别在于请求 URL 和输入参数都包含在操作定义中。操作名称与上一节中的名称相同,称为“getCar”。此操作也执行相同的功能,它获取制造商、型号和汽车年份,并获取汽车信息。
这是如何使用此 ngResource 对象。在相同的服务定义中,我创建了这个名为 getCar() 的服务方法:
svc.getCar = function (make, year, model) {
   return restSvc.getCar({
      make: make,
      year: year,
      model: model
   }).$promise;
};
此服务方法与上一节中显示的方法功能相同。它调用 ngResource 对象,并调用名为 getCar() 的操作。然后返回 promise。
在“app.js”中,您可以看到如何使用 service 方法:
vm.clickGetCar2 = function () {
   sampleRestService.getCar("honda", 1997, "civic").then(function (result) {
      if (result) {
         vm.getCar2Succeeded = true;
         vm.getCar2Response = JSON.stringify(result, null, 3);
      } else {
         vm.getCar2Failed = true;
         vm.getCar2ErrorMsg = "Error occurred.";                  
      }
   }, function(error) {
      vm.getCar2Failed = true;
      vm.getCar2ErrorMsg = "Error occurred.";
   });
};
从这个例子可以看出,ngResource 的使用也可以分为三个部分:
- 第一部分是使用 ngResource$resource定义一个ngResource对象,该对象具有可以与后端 Web 服务通信的操作。
- 使用 ngResrouce对象与后端执行数据交换,然后返回 promise 对象。
- 使用 promise 来处理来自后端服务的实际数据,以及可能的错误。
此时,我们已经看到了 ngResource 获取和处理数据的方式。我可以告诉您,除了某些细微的差异外,这三个部分看起来都相同。在下一节中,我将讨论这些细微的差异。
以各种方式处理 HTTP 请求
现在我们知道了如何使用一个带有多个操作的 ngResource 对象,我们可以讨论如何使用 ngResource 对象来处理最常见的 HTTP 请求。在以下子节中,我们将看到如何使用 ngResource 对象来处理 HTTP Get、HTTP Post、HTTP Put 和 HTTP Delete 操作类型的请求。
处理 HTTP Get 请求
在前面的示例中,我们已经看到了 ngResource 处理 HTTP GET 请求的方式,其中输入参数是 URL 路径的一部分。例如,前面示例中使用的 URL 是:
https://:8080/getCar/honda/1997/civic
如所示,ngResource 将操作定义为:
var restSvc = $resource(null, null, {
   "getCar": {
      url: "./getCar/:make/:year/:model",
      method: "get",
      isArray: false,
      params: {
         make: "@make",
         year: "@year",
         model: "@model"
      }
   },
   ...
});
定义如下所示:
- url属性的值为“- ./getCar/:make/:year/:model”。输入变量用“- :”前缀定义。
- 然后是 params属性。上面的定义表明params期望一个对象。对象的属性按名称映射。我所做的是使名称与object属性名称相同。
当使用该操作时,操作如下:
svc.getCar = function (make, year, model) {
   return restSvc.getCar({
      make: make,
      year: year,
      model: model
   }).$promise;
};
ngResource 对象称为“restSvc”,对象方法 getCar() 接受一个具有三个属性的对象:“make”、“year”和“model”。该对象将被视为“restSvc”操作中定义的 params 的值。
在不同的场景中,假设 HTTP 请求仍然是 HTTP GET 请求。不是在 URL 路径中有输入参数,而是它们是请求参数。URL 路径如下所示:
https://:8080/getCar?make=honda&year=1997&model=civic
使用 ngResource 来处理此类 URL,ngReosurce 的定义与之前的类似,这里是:
var restSvc = $resource(null, null, {
   ...
   "getCarReq": {
      url: "./getCarReq",
      method: "get",
      isArray: false,
      params: {
         make: "@make",
         year: "@year",
         model: "@model"
      }
   },
   ...
});
通过 ngResource 对象(在此示例中称为“restSvc”)使用此 ngReosurce 操作的方式与前面的示例相同。以下是代码,请自行查看:
svc.getCarReq = function (make, year, model) {
   return restSvc.getCarReq({
      make: make,
      year: year,
      model: model
   }).$promise;
};
不同之处在于,在前面的示例中,URL 包含可以从 params 映射到 path 变量的输入变量。在此示例中,params 中的值默认映射为请求参数。
这两个示例都只从服务器端返回单个对象。返回对象列表怎么样?实际上很容易做到。在示例程序中,我有一个 URL 如下:
https://:8080/getAllCars?maker=honda&model=civic
请求参数是虚拟值,URL 保证会返回汽车信息列表作为 JSON 数组。为了在客户端处理此问题,我已经定义了以下 ngReosurce 操作:
var restSvc = $resource(null, null, {
   ...
   "getAllCars": {
      url: "./getAllCars",
      method: "get",
      isArray: true,
      params: {
         maker: "@maker",
         model: "@model"
      }
   }
});
唯一不同的是 isArray 的值,它设置为 true。这非常重要,无论您使用哪种 HTTP 方法,只要您期望请求返回单个对象,isArray 属性就应设置为 false。如果它返回对象数组,isArray 属性就应设置为 true。如果对此属性不小心,您将收到运行时异常。
处理 HTTP Post 请求
这些都是简单的事情。让我们来看一个更复杂的场景。假设我们有一个 URL,并且与之交互的唯一方式是使用 HTTP POST。输入对象必须是 JSON 格式。这是 URL:
https://:8080/addCar
要处理此类场景,ngResource 操作定义略有不同:
- 此新 post 操作的 URL 将不同。除非您使用相同的 URL 和不同的 HTTP 方法来区分它们,否则操作的 URL 应始终不同。
- 方法应该是“post”而不是“get”。
- 我们必须使用名为“data”的属性,而不是使用“params”属性来指定输入数据如何映射到请求。
这是此 HTTP Post 示例的 ngResource 操作的定义:
var restSvc = $resource(null, null, {
   ...
   "addCar": {
      url: "./addCar",
      method: "post",
      isArray: false,
      data: "@addCar"
   },
   ...
});
“data”的值映射有点不同。我没有指定一个对象,而是为其分配了一个 string。“@addCar”的 string 值表示当 ngReosurce 对象的方法(即“addCar”)被调用时,以“addCar”命名的传入参数将被指定为请求的数据。默认情况下,数据属性在传递给后端 Web 服务时会被转换为 JSON string。
这是使用此 ngResource 操作的代码:
svc.addCar = function (addCarReq) {
   return restSvc.addCar(addCarReq).$promise;
};
service 方法接受一个名为 addCarReq 的参数,该参数将被传递给 ngResource 对象 restSvc 的 addCar 操作。这将是“addCar”参数的值。服务对象如何用于此操作与之前几乎相同:
vm.clickAddCar = function () {
   var addCarReq = {
      maker: "toyota",
      model: "camry",
      yearOfManufacturing: 1997,
      suggestedRetailPrice: 21800,
      fullPrice: 22395
   };
   
   sampleRestService.addCar(addCarReq).then(function (result) {
      if (result) {
         vm.addCarSucceeded = true;
         vm.addCarResponse = JSON.stringify(result, null, 3);
      } else {
         vm.addCarFailed = true;
         vm.addCarErrorMsg = "Error occurred.";                  
      }
   }, function(error) {
      vm.addCarFailed = true;
      vm.addCarErrorMsg = "Error occurred.";
   });
};
这只是一种将数据传递到后端 Web 服务的方式。在过去,当 Web 开发人员使用 HTML 并进行表单提交时,它使用“application/x-www-form-urlencoded”的内容类型。当您必须处理少量数据时,这是一种与后端 Web 服务通信的非常方便的方式。例如,您有一个请求要激活或禁用 car 模型。您只需要汽车模型的 ID 和一个布尔值。您需要将它们包装成一个对象并传递给后端 Web 服务吗?不。您可以定义一个接受这两个输入数据值作为参数的操作方法。这是我的示例的 Spring REST 操作方法,仅供 Java 参考:
@RequestMapping(value="/carForPurchase",
   method = RequestMethod.POST,
   consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<GenericResponse> carForPurchase(
   @RequestParam("carId")      
   String carId,
   @RequestParam("readyToPurchase")
   boolean readyToPurchase
)
{
   System.out.println("car Id: " + carId);
   System.out.println("ready To Purchase: " + readyToPurchase);
   
   GenericResponse resp = new GenericResponse();
   if (carId == null || carId.equals(""))
   {
      resp.setId("");
      resp.setSuccess(false);
      resp.setDetailMessage("No record updated. Invalid input.");
   }
   else
   {
      resp.setId(carId);
      resp.setSuccess(true);
      resp.setDetailMessage("Car is now available for purchase.");
   }
   
   return ResponseEntity.ok(resp);
}
如您所见,方法输入参数是 String 和 Boolean 类型的原始对象。这方面最棒的是,我不需要定义一个对象类型来包装两个属性。但是,这在 JavaScript 端变得稍微复杂一些。为了支持这种情况,在 AngularJS 端,我们需要做一些新的事情:
- 对于 ngResource操作,方法应该是“post”而不是“get”。并且 URL 应该是新 URL。
- 输入数据值仍然通过 ngResource操作中的“data”属性传入。
- 我们需要用新的内容类型覆盖 HTTP 标头。
- 最后,我们需要有一个数据转换方法,可以将数据对象更改为 x-www-urlencoded string。并且我们需要将一些新对象注入到 sample service 模块中。
首先,我们需要向 sample service 模块添加一些新的依赖注入。这是:
mod.factory("sampleRestService", [ "$resource", "$httpParamSerializer",
   function ($resource, $httpParamSerializer) {
   ...
   }
]);
我们需要的依赖注入称为 $httpParamSerializer。这是 AngularJS 核心 http 模块的一部分。所以我不必注入模块。它可以将实际数据对象转换为 url 编码的 string。要做到这一点,我们需要一个新的本地方法:
function uriEncodedParams(data) {
   var retVal = "";
   if (data) {
      retVal =  $httpParamSerializer(data);
   }
   
   return retVal;
}
这个方法所做的就是检查数据对象是否不为 null 或未定义。然后它将数据对象传递给 $httpParamSerializer() 方法,该方法又返回一个 x-www-urlencoded string,表示 data 对象。该 string 看起来像这样:
carId=ff7c05f0e38a4c70a5bb821081e59efd&readyToPurchase=true
现在,我们有足够的资源来定义所需的 ngReource 操作:
var restSvc = $resource(null, null, {
   ...
   "carForPurchase": {
      url: "./carForPurchase",
      method: "post",
      isArray: false,
      headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" },
      transformRequest: uriEncodedParams
   },
   ...
});
与前面的 HTTP Post 请求处理示例相比,唯一的区别是:
- 我们添加了一个名为“headers”的新属性。此属性将覆盖请求的 HTTP 标头。在这种情况下,我们只覆盖“Content-Type”标头。
- 我们必须添加的第二个属性是“transformRequest”。这相当于“data”或“params”属性。此“transformRequest”的值是uriEncodedParams方法的名称。它的作用是将数据对象转换为我们想要的格式。在这种情况下,我们想要x-www-urlencoded string。
看它是多么简单。它是通过约定完成的。传递到此 ngResource 操作的任何数据都将传递到本地方法 uriEncodedParams(),该方法执行转换。然后将转换后的请求数据添加到请求中。
这是调用此 angResource 操作的代码:
svc.carForPurchase = function (req) {
   return restSvc.carForPurchase(req).$promise;
};
这是客户端调用此 service 方法的代码:
vm.clickCarForPurchase = function () {
   var carForPurchaseReq = {
      carId: "ff7c05f0e38a4c70a5bb821081e59efd",
      readyToPurchase: true
   };
   
   sampleRestService.carForPurchase(carForPurchaseReq).then(function (result) {
      if (result) {
         vm.carForPurchaseSucceeded = true;
         vm.carForPurchaseResponse = JSON.stringify(result, null, 3);
      } else {
         vm.carForPurchaseFailed = true;
         vm.carForPurchaseErrorMsg = "Error occurred.";                  
      }
   }, function(error) {
      vm.carForPurchaseFailed = true;
      vm.carForPurchaseErrorMsg = "Error occurred.";
   });
};
从客户端调用代码可以看出,与我们之前看到的其他代码相比,没有什么大的区别。我们将其包装在一个对象中,将其传递给 service 方法,然后 service 方法调用 ngResource 对象的动作方法。最后,当 HTTP 请求异步处理时,结果处理将基本相同。
此时,您已经看到了最复杂的场景。事实证明它非常简单,只要您了解它的工作原理即可。:)
处理其他两种 HTTP 方法类型的请求
还有另外两种 HTTP 方法,一种称为“Put”。另一种称为“Delete”。我们有四种 HTTP 请求方法是有原因的,它们与数据库的 CRUD 操作密切相关。方法“Post”主要用于添加资源。方法“Get”主要用于检索数据。方法“Put”用于在资源尚未添加时添加资源。如果资源已添加,则“Put”中的数据将用于更新资源。最后,方法“Delete”请求方法将删除资源。
由于 HTTP Put 请求与 HTTP Post 请求相似,我将创建一个简单的示例 ngResource 操作来练习 HTTP Put 方法。以下是 ngResource 操作的定义:
var restSvc = $resource(null, null, {
   ...
   "updateCar": {
      url: "./updateCar",
      method: "put",
      isArray: false,
      data: "@addCar"
   },
   ...
});
如所示,此操作与 HTTP Post 请求的 ngResource 操作之间没有太大区别。一个容易记住的重要概念是,您可以使用 ngResource 语法用 HTTP Post 完成的任何事情,都可以用 HTTP Put 完成。
调用此 ngResource 操作的 service 方法如下所示:
svc.updateCar = function (req) {
   return restSvc.updateCar(req).$promise;
};
在客户端,service 方法的调用和处理方式相同。所以我不会在此处发布代码。我想展示的最后一件事是如何处理 HTTP Delete。
另一个要记住的重要概念是,HTTP Delete 与 HTTP Get 请求相似。Data 必须是 URL 路径的一部分,或作为请求参数。所以您使用 AngularJS 处理 HTTP Get 请求时所做的一切,在语法上都可以用 HTTP Delete 请求做同样的事情。
这是处理 HTTP Delete 请求的 ngResource 操作的定义:
var restSvc = $resource(null, null, {
   ...
   "deleteCar": {
      url: "./deleteCar",
      method: "delete",
      isArray: false,
      params: {
         id: "@id",
         maker: "@maker",
         model: "@model",
         year: "@year"
      }
   },
   ...
});
在此示例中,request URL 接受 request 参数中的输入数据,而不是作为路径变量。我使用“params”将一系列数据值传递给后端服务。
调用 ngResource 操作的服务方法如下所示:
svc.deleteCar = function (req) {
   return restSvc.deleteCar(req).$promise;
};
如果您将其与处理 HTTP Get 请求的示例进行比较,您会发现两者都相似。这很直接。
这些就是所有示例,展示了如何使用 ngResource 处理 HTTP 请求。它们非常直接。只要您能理解 AngularJS 的语法,或者至少模仿处理不同请求的方式,您就可以快速掌握 ngResource 的工作原理。
如何运行示例项目
要运行示例项目,首先需要转到 /src/main/resources/static/assets 文件夹及其子文件夹,找到所有 *.sj 文件,并将它们重命名为 *.js。
所有 *.js 文件恢复后,使用命令行,转到项目根文件夹并运行以下命令:
mvn clean install
当您第一次运行此程序时,将花费一些时间并下载所有依赖项 - jar 文件。然后,它将编译并将二进制文件打包到一个 jar 文件中。在同一个根文件夹中,运行以下命令启动应用程序:
java -jar target\hanbo-ngresource-sample-1.0.1.jar
应用程序成功启动后,您可以导航到以下 URL 查看示例应用程序:
https://:8080/index.html

一旦您可以看到上面的屏幕截图,就表示您已成功启动了示例应用程序。您可以转到每个部分,通过点击“Test”按钮来运行示例。通过点击“Reset”按钮来重置该部分。
摘要
如果您已阅读到此,我想您已经享受了本文丰富的信息内容。我不得不说,撰写本文的过程非常有趣。在本文中,我讨论了使用 ngResource(或 Angular $resource 服务)发送 HTTP 请求、接收响应以及处理响应数据的常用方法。创建了三个示例来展示如何处理 HTTP Get 请求。这些示例显示了如何使用路径变量、请求参数发送 HTTP Get 请求,以及如何处理数组而不是单个对象的响应。然后,我创建了两个示例来展示 HTTP Post 的工作原理,一个是如何使用 JSON 格式的数据进行 post 请求。另一个是如何使用 x-www-urlencoded string 进行 post 数据。最后,我介绍了 HTTP Put 和 HTTP Delete 与 ngResource 的使用。这些示例应该涵盖大多数实际场景。希望您喜欢阅读本文。祝您好运!
历史
- 2019/05/14 - 初稿



