在 Ember 中编写 Or 筛选器



我想用Ember编写一个Or过滤器。我要实现的过滤器如下:

(end_date <= filter_end_date && end_date >= filter_start_date) || (start_date >= filter_start_date && start_date <= filter_end_date) || (start_date <= filter_start_date && end_date >= filter_end_date)

我正在将所有过滤器收集在一起,然后在发送查询时传递它:

filterOptions: [
{
name : 'state',
op   : 'eq',
val  : 'published'
}
]

查询如下:

return this.get('store').query('event', {
sort   : 'starts-at',
filter : filterOptions
});

我浏览了文档,但没有找到任何东西。对此筛选器进行建模的最佳方法是什么?

您所要求的是 REST API 使用的过滤策略。这不是余烬特有的.js。store服务,即您正在使用query方法,由 ember-data 提供。Ember-data 是 ember 的默认持久层,默认情况下将 ember-cli 的蓝图包含在新项目中。

默认情况下,ember-data 正在实现 JSON API 规范。该规范注册了用于过滤的filter查询参数,但与使用的过滤策略无关:

注意:JSON API 与服务器支持的策略无关。筛选器查询参数可用作任意数量的筛选策略的基础。(来源(

只有筛选建议,它解决了按关联记录的 ID 进行筛选的问题:

建议希望支持筛选 基于关联的资源集合通过允许查询来实现 将筛选器与关联名称组合在一起的参数。

例如,以下是对所有关联注释的请求 与特定帖子:

GET/comments?filter[post]=1 HTTP/1.1

嵌入 ember-data 的唯一过滤策略是按所请求资源的多个 ID 进行过滤。如果使用内置的 JSONAPIAdapter 并且coalesceFindRequests选项true,则使用它。它默认为false.在这种情况下,ember-data 将对一个资源的特定记录的多个请求合并到一个 GET 查询中,以避免触发多个查询。它使用filter查询参数以及用于过滤的属性(id(括在方括号和逗号分隔的ID列表中。例如,对 ID 为 1 和 2 的帖子的/posts端点的查询如下所示:GET /posts?filter[id]=1,2

因此,将其放在一起,所有现有部分仅按(关联(资源的ID进行过滤。

JSON API 规范与过滤策略无关是有充分理由的:一个非常合适的过滤策略是高度特定于应用程序的。在 REST API 上支持 SQL 的全部功能可能会给 API 带来很大的性能问题。

但是,有很多复杂的过滤策略,这些策略可以实现并很好地符合JSON API中的建议和coalesceFindRequests余烬数据的功能。

例如,可以采用OpenStack使用的过滤语法。那个允许将用冒号分隔的运算符添加到过滤器中。有了这个查询,请求2018年1月1日之后发布的所有帖子的查询将如下所示:GET /posts?filter[published-at]=gt:2018-01-01。请注意,我还假设使用驼峰大小写的字段名称和 ISO-8601 日期字符串。但是,此语法不支持or运算符。有一些论据认为不要将or运算符的复杂性置于 REST API 过滤策略中。通过使用单独的查询并合并返回的集合,可以轻松获得该选项。

更复杂的筛选策略是资源查询语言 (RQL(。那个用等号分隔运算符和值。因此,上面用作示例的请求如下所示:GET /posts?filter[published-at]=gt=2018-01-01RQL 还支持or运算符使用偏执来分组由竖线分隔的表达式。对 2018 年 1 月 1 日之后但 2018 年 2 月 1 日之前发布的帖子的查询如下所示:GET /posts?(filter[published-at]=gt=2018-01-01|filter[published-at]=lt=2018-02-01)但是,有人可能会争辩说,这不是查询参数的非常常见的语法,并且可能会导致 Web 服务器、缓存、代理等问题。

由于 ember-data 将store.query()的第二个参数作为data设置直接传递给jQuery.ajax(),因此您可以完全自由地根据应用程序需求选择过滤策略。

是的,@jelhan是正确的。我们使用Flask-REST-JSONAPI作为过滤系统。过滤系统与资源列表管理器使用的数据层完全相关。因此,我使用 https://flask-rest-jsonapi.readthedocs.io/en/latest/filtering.html 作为参考,并编写了如下过滤器:

dateFilterWithEndDate: computed('start_date', 'end_date', function() {
return EmberObject.create(
{
or:
[
{
and: [
{
name : 'starts-at',
op   : 'ge',
val  : this.get('start_date')
},
{
name : 'starts-at',
op   : 'le',
val  : this.get('end_date')
}
]
},
{
and: [
{
name : 'ends-at',
op   : 'ge',
val  : this.get('start_date')
},
{
name : 'ends-at',
op   : 'le',
val  : this.get('end_date')
}
]
},
{
and: [
{
name : 'starts-at',
op   : 'le',
val  : this.get('start_date')
},
{
name : 'ends-at',
op   : 'ge',
val  : this.get('end_date')
}
]
}
]
}
);
}),
dateFilterBasic: computed('start_date', function() {
return EmberObject.create(
{
or: [
{
name : 'starts-at',
op   : 'ge',
val  : this.get('start_date')
},
{
name : 'ends-at',
op   : 'ge',
val  : this.get('start_date')
}
]
}
);
}),

我将其添加到查询方法中的filter参数中,如下所示:

if (endDate) {
filterOptions.pushObject(this.get('dateFilterWithEndDate'));
} else {
filterOptions.pushObject(this.get('dateFilterBasic'));
}
return this.get('store').query('event', {
sort   : 'starts-at',
filter : filterOptions
});

最新更新