是否可以将参数化 URL 模板与 angular $http 服务一起使用

Is it possible to use parameterized URL templates with angular $http service

我正在为我的 RESTful api 使用 $resource 并且喜欢参数化 URL 模板,例如 'api/clients/:clientId'

这对 CRUD 操作非常有用。然而,我的一些 api 只是报告或只读端点,不需要完整的 RESTful 处理。我觉得为这些使用 $resource 而是使用带有 $http 的自定义数据服务有点过分了。

唯一的缺点是我丢失了参数化的 URL 模板。我很想定义一个 url like'api/clients/:clientId/orders/:orderId' 并且只传递 { clientId: 1, orderId: 1 }。我意识到我可以动态构建 url 但希望 $http 支持参数化模板,但我还没有找到它。

祝一切顺利

更新 7/5

我在搜索中遗漏的词是 'Interpolate'。当我搜索 'url interpolation in angular $http' 时会出现更多信息。简短的回答看起来是 'No' $http 不支持 url 插值。然而,有一些相当简单的方法可以实现这一点。

1.使用 $interpolate:

$interpolatehere

的文档
var exp = $interpolate('/api/clients/{{clientId}}/jobs/{{jobId}}', false, null, true);
var url = exp({ clientId: 1, jobId: 1 });


2。自己写url插值函数

本·纳德尔 (Ben Nadel) 在这个确切的主题 here 上有很好的 post。


3。从 angular-resource

窃取功能

查看 angular-resource.js 中 Route.prototype 的 setUrlParams。这相当简单。

使用 $interpolate 的示例数据服务

(function () {
    'use strict';

    var serviceId = 'dataservice.jobsReports';

    angular.module('app').factory(serviceId, ['$http', '$interpolate', function ($http, $interpolate) {

        var _urlBase = 'http://localhost:59380/api';
        var _endPoints = {
            getJobsByClient: {
                url: 'Clients/{{clientId}}/Jobs',
                useUrlInterpolation: true,
                interpolateFunc: null
            }
        };

        // Create the interpolate functions when service is instantiated
        angular.forEach(_endPoints, function (value, key) {
            if (value.useUrlInterpolation) {
                value.interpolateFunc = $interpolate(_urlBase + '/' + value.url, false, null, true);
            }
        });

        return {
            getJobsByClient: function (clientId) {
                var url = _endPoints.getJobsByClient.interpolateFunc({ clientId: clientId });
                return $http.get(url);
            }
        };

    }]);

})();

为了防止 "unanswered" 已回答...

1.使用 $interpolate:

$interpolatehere

的文档
var exp = $interpolate('/api/clients/{{clientId}}/jobs/{{jobId}}', false, null, true);
var url = exp({ clientId: 1, jobId: 1 });


2。自己写url插值函数

本·纳德尔 (Ben Nadel) 在这个确切的主题 here 上有很好的 post。


3。从 angular-resource

中窃取功能

查看 angular-resource.js 中 Route.prototype 的 setUrlParams。相当简单。

使用 $interpolate

的示例数据服务
(function () {
    'use strict';

    var serviceId = 'dataservice.jobsReports';

    angular.module('app').factory(serviceId, ['$http', '$interpolate', function ($http, $interpolate) {

        var _urlBase = 'http://localhost:59380/api';
        var _endPoints = {
            getJobsByClient: {
                url: 'Clients/{{clientId}}/Jobs',
                useUrlInterpolation: true,
                interpolateFunc: null
            }
        };

        // Create the interpolate functions when service is instantiated
        angular.forEach(_endPoints, function (value, key) {
            if (value.useUrlInterpolation) {
                value.interpolateFunc = $interpolate(_urlBase + '/' + value.url, false, null, true);
            }
        });

        return {
            getJobsByClient: function (clientId) {
                var url = _endPoints.getJobsByClient.interpolateFunc({ clientId: clientId });
                return $http.get(url);
            }
        };

    }]);

})();

对于 URL 模板,有一个明确定义的建议:RFC 6570

您可以在 Github 上找到一种实现方式:bramstein/url-template

很简单。这是一个 AngularJS 服务,它使用了一个实现 RFC 6570 标准的库:

var app=angular.module('demo',[]);


app.service('UserStore',function () {
  var baseUrl=urltemplate.parse('/rest/v1/users{/_id}');
  return {
    load:function(id){
      return $http.get(baseUrl.expand({_id:id}));
    },
    save:function (profile) {
      return baseUrl.expand(profile);
      //return $http.post(baseUrl.expand(profile),profile);
    },
    list:function (id) {

    }
  }
});

app.controller('demoCtrl',function(UserStore){
  this.postUrlOfNewUser=UserStore.save({name:"jhon"});
  this.postUrlOfExistingUser=UserStore.save({_id:42,name:"Arthur",accessory:"towel"});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdn.rawgit.com/bramstein/url-template/master/lib/url-template.js"></script>
<div ng-app="demo">
  <div ng-controller="demoCtrl as ctrl">
    <div>New user POST URL: {{ctrl.postUrlOfNewUser}}</div>
    <div>Existing user POST URL: {{ctrl.postUrlOfExistingUser}}</div>
  </div>
</div>
<script>
</script>

如您所见,标准甚至处理可选的 PATH 组件。它使一切变得轻而易举!

你也可以用“.”要么 ”;” -- 用于矩阵符号甚至扩展查询字符串!