在 Ember 中写一个 Or 过滤器
Write an Or filter in Ember
我想在 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 使用的过滤策略。这不是 ember.js 特有的。您正在使用的 query
方法的 store
服务由 ember-data 提供。 Ember-data 是 ember 的默认持久层,默认包含 ember-cli 的蓝图到新项目中。
默认情况下 ember-data 正在执行 JSON API specification。该规范注册了用于过滤的 filter
查询参数,但不知道所使用的过滤策略:
Note: JSON API is agnostic about the strategies supported by a server. The filter query parameter can be used as the basis for any number of filtering strategies. (Source)
只有一个过滤建议,它解决了通过关联记录的 ID 进行过滤的问题:
It’s recommended that servers that wish to support filtering of a
resource collection based upon associations do so by allowing query
parameters that combine filter with the association name.
For example, the following is a request for all comments associated
with a particular post:
GET /comments?filter[post]=1 HTTP/1.1
ember-data 中内置的唯一过滤策略是通过所请求资源的多个 ID 进行过滤。如果使用内置 JSONAPI 适配器并且 coalesceFindRequests
option 是 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.
带来很大的性能问题
但是有很多复杂的过滤策略,可以实现并且很符合JSONAPI和ember的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通过store.query()
directly forward to jQuery.ajax()
的第二个参数作为data
设置,您完全可以根据您的应用需求自由选择过滤策略。
是的,@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
});
我想在 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 使用的过滤策略。这不是 ember.js 特有的。您正在使用的 query
方法的 store
服务由 ember-data 提供。 Ember-data 是 ember 的默认持久层,默认包含 ember-cli 的蓝图到新项目中。
默认情况下 ember-data 正在执行 JSON API specification。该规范注册了用于过滤的 filter
查询参数,但不知道所使用的过滤策略:
Note: JSON API is agnostic about the strategies supported by a server. The filter query parameter can be used as the basis for any number of filtering strategies. (Source)
只有一个过滤建议,它解决了通过关联记录的 ID 进行过滤的问题:
It’s recommended that servers that wish to support filtering of a resource collection based upon associations do so by allowing query parameters that combine filter with the association name.
For example, the following is a request for all comments associated with a particular post:
GET /comments?filter[post]=1 HTTP/1.1
ember-data 中内置的唯一过滤策略是通过所请求资源的多个 ID 进行过滤。如果使用内置 JSONAPI 适配器并且 coalesceFindRequests
option 是 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.
带来很大的性能问题但是有很多复杂的过滤策略,可以实现并且很符合JSONAPI和ember的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通过store.query()
directly forward to jQuery.ajax()
的第二个参数作为data
设置,您完全可以根据您的应用需求自由选择过滤策略。
是的,@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
});