我想在Ember中编写一个raw-loader
过滤器。我要实现的过滤器如下:
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'
}
]
我浏览了文档,但没有找到任何东西。为该过滤器建模的最佳方法是什么?
答案 0 :(得分:2)
您要的是REST API使用的过滤策略。这不是特定于ember.js。 store
服务(您使用的query
方法)由ember-data提供。 Ember-data是ember的默认持久层,默认情况下将ember-cli蓝图包含到新项目中。
默认情况下,余烬数据正在实现JSON API specification。该规范注册了filter
查询参数以进行过滤,但是与所使用的过滤策略无关:
注意:JSON API与服务器支持的策略无关。过滤器查询参数可以用作许多过滤策略的基础。 (Source)
只有一个过滤建议,该建议通过关联记录的ID解决过滤问题:
建议希望支持过滤 基于关联的资源收集通过允许查询来实现 将过滤器与关联名称结合在一起的参数。
例如,以下是对所有关联评论的请求 带有特定帖子:
GET / comments?filter [post] = 1 HTTP / 1.1
嵌入到余烬数据中的唯一过滤策略是有关通过请求资源的多个ID进行过滤。如果使用内置JSONAPIAdapter且coalesceFindRequests
option为true
,则使用它。默认为false
。在那种情况下,余烬数据将对一个资源的特定记录的多个请求合并到一个GET查询中,以避免触发多个查询。它使用filter
查询参数以及方括号内的用于过滤(id
)的属性和以逗号分隔的ID列表。例如。对/posts
端点进行ID为1和2的帖子的查询将类似于:GET /posts?filter[id]=1,2
。
因此,将所有现有部分放在一起,仅涉及按(关联)资源的ID进行过滤。
有一个很好的理由说明JSON API规范对过滤策略不可知:一个非常合适的过滤策略是高度特定于应用程序的。在REST API上支持SQL的全部功能可能会给API带来严重的性能问题。
但是,有很多复杂的过滤策略,可以实施并完全符合JSON API中的建议以及ember-data的coalesceFindRequests
功能。
例如,可以采用filtering syntax used by OpenStack。这样一来,就可以将由冒号分隔的运算符添加到过滤器中。通过该查询,请求所有2018年1月1日之后发布的帖子的查询将类似于:GET /posts?filter[published-at]=gt:2018-01-01
。请注意,我还假设使用驼峰式字段名和ISO-8601日期字符串。但是,此语法不支持or
运算符。对于不将or
运算符的复杂性置于REST API过滤策略中,存在一些争论。通过使用分开的查询并合并返回的集合,您可以轻松地拥有该选项。
一种更复杂的过滤策略是Resource Query Language (RQL)。那是用等号将运算符和值分开。因此,上面示例中的请求看起来像:GET /posts?filter[published-at]=gt=2018-01-01
RQL还支持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通过data
设置将store.query()
的第二个参数直接传递给jQuery.ajax()
,因此您完全可以根据应用程序的需求自由选择过滤策略。>
答案 1 :(得分:0)
是的,@ jelhan是正确的。我们正在使用Flask-REST-JSONAPI作为过滤系统。过滤系统与ResourceList管理器使用的数据层完全相关。因此,我使用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
});