twi*_*inb 3 javascript arrays odata angularjs angularjs-http
我有一个用于查询 OData 服务的角度提供程序。
现在我正在尝试在该提供程序上构建 $filter 函数,以便我可以在整个应用程序中使用它。
我遇到的问题,到目前为止还没有解决,是 URL 的查询部分需要以 '$filter=' 开头,当有一个过滤器但有多个过滤器时,我可以很好地处理添加为“和{查询在这里}”。
示例查询将是:
http://www.example.com/odata/Restaurants/?$filter=id eq 2 and city eq 'Los Angeles' and substringof("Lagasse", chef)&$top=20
Run Code Online (Sandbox Code Playgroud)
我将数组中的所有过滤器发送给提供者。理想情况下,我会使用 "$filter=#{firstFilter}" 作为数组中的第一个过滤器,其余的过滤器使用 " 和 #{remainingFilter}" 但我不确定如何构建此代码。
我当前的代码使用多个 if 语句来检查过滤器是否存在,但由于构建 url 的性质,它始终强制使用过滤器之一。我想避免这种情况。
例如:
var filter = "$filter=id eq 2";
if (city) {
filter += " and city eq #{cityName}";
}
if (chef) {
filter += " and substringof(#{chefName}, chef)";
}
Run Code Online (Sandbox Code Playgroud)
现在每次用户输入查询时,他们都必须指定一个 id。
我们没有使用 BreezeJS、JayData 或任何其他库。严格来说是 AngularJS,特别是 $http,而不是 $resource。
您可以使用odata-filter-builder为OData URL 查询选项构建$filter 部分。
然后只需$http与配置参数一起使用。
简短示例:
var filter = ODataFilterBuilder()
.eq('id', 2)
.eq('city', 'Los Angeles')
.and('substringof("Lagasse", chef)')
.toString();
$http
.get(resourceUrl, {params: {$filter: filter, $top: 20}})
.then(function(response) {
// Handle response
})
Run Code Online (Sandbox Code Playgroud)
完整示例:
angular
.module('OData', [])
.constant('ODataFilterBuilder', ODataFilterBuilder)
.factory('ODataService', function($http) {
return {
load: function(resourceUrl, queryParams) {
return $http.get(resourceUrl, {params: queryParams})
.then(function(response) {
return response.data.value;
});
}
}
});
angular
.module('app', ['OData'])
.controller('appController', function($http, ODataService, ODataFilterBuilder, $httpParamSerializer) {
// 1. inject ODataFilterBuilder
// use short name for filter builder
var f = ODataFilterBuilder;
// 2. build filter
var filter = f()
.eq('id', 2)
.eq('city', 'Los Angeles')
.and('substringof("Lagasse", chef)')
// 3. creater odata query params
var queryParams = {
$filter: filter.toString(),
$top: 20
// TODO: add other params
};
// 4. prepare odata resourse URL
var odataServiceUrl = 'http://path/to/odata/service/';
var odataResourseUrl = odataServiceUrl + 'entity';
// 5. Do http request with odataResourseUrl and queryParams
// use ODataService or angular $http service
// ODataService
// .load(odataResourseUrl, queryParams)
// .then(function(value) {
// // handle value
// });
// OR
// $http.get(odataResourseUrl, {params: queryParams})
// .then(function(respons) {
// // handle respons.data.value
// });
// Result examles:
// NOTE: $httpParamSerializer - default $http params serializer that converts objects to strings
var queryParamsSerialised = $httpParamSerializer(queryParams);
// put values to 'this' to use it in html
this.queryParams = queryParams;
this.queryParamsSerialised = queryParamsSerialised;
this.queryUrl = odataResourseUrl + '?' + queryParamsSerialised;
});Run Code Online (Sandbox Code Playgroud)
<div ng-app="app" ng-controller="appController as vm">
<pre>queryParams: {{vm.queryParams|json}}</pre>
<pre>queryParamsSerialised: {{vm.queryParamsSerialised}}</pre>
<pre>queryUrl: {{vm.queryUrl}}</pre>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="https://npmcdn.com/odata-filter-builder@^0.1/dist/odata-filter-builder.js"></script>Run Code Online (Sandbox Code Playgroud)