Вчера я потратил много времени, пытаясь включить фильтр (отражающий спецификацию JSONAPI ) в параметры запроса части приложения Ember.С Ember Data достаточно просто передать массив фильтров в конечную точку, проблема, которую я имею, заключается в отражении этого массива фильтров в параметрах запроса для определенного маршрута.Примечание: другие параметры, не относящиеся к массиву, работают нормально.
TL; DR Я безуспешно пробовал различные варианты, и у меня есть решение, которое на самом деле кажется неудовлетворительным и совсем не СУХОЙ.Я полагаю, что многие другие, должно быть, решили эту проблему и наверняка нашли лучшее решение.Прочтите подробности того, что я пробовал до сих пор.
Я начал с чего-то подобного (я изначально предполагал, что это сработает, прочитав Ember документы по параметрам запроса ):
Контроллер:
import Controller from '@ember/controller';
export default Controller.extend({
queryParams: ['sort', 'filter'],
sort: 'id',
init() {
this._super(...arguments);
this.set('filter', []);
},
});
Маршрут:
import Route from '@ember/routing/route';
export default Route.extend({
queryParams: {
filter: {
refreshModel: true
},
sort: {
refreshModel: true
}
},
model(params) {
console.log(JSON.stringify(params)); // filter is always []
return this.get('store').query('contact', params);
}
});
Приемочный тест (это было только доказательством концептуального теста, прежде чем я начал на более сложных вещах):
test('visiting /contacts with query params', async function(assert) {
assert.expect(1);
let done = assert.async();
server.createList('contact', 10);
server.get('/contacts', (schema, request) => {
let params = request.queryParams;
assert.deepEqual(
params,
{
sort: '-id',
"filter[firstname]": 'wibble'
},
'Query parameters are passed in as expected'
);
done();
return schema.contacts.all();
});
await visit('/contacts?filter[firstname]=wibble&sort=-id');
});
Независимо от того, как я настраивал приведенный выше код, params.filter всегда был [] в функции модели маршрута.
Я искал лучшие практики в отношении того, что может показаться распространенным.дела, но не нашли ничего недавнего. Решение sarus здесь с ноября 2015 года работает, но означает, что каждый возможный ключ фильтра должен быть жестко задан в контроллере и маршруте, что мне кажется далеко не идеальным.Только представьте, что вы делаете это для 20 возможных ключей фильтра!Используя решение sarus, вот код, который работает для вышеуказанного приемочного теста, но, как я уже сказал, представьте себе, что нужно жестко закодировать 20+ потенциальных ключей фильтра:
Контроллер:
import Controller from '@ember/controller';
export default Controller.extend({
queryParams: ['sort',
{ firstnameFilter: 'filter[firstname]' }
],
sort: 'id',
firstnameFilter: null,
init() {
this._super(...arguments);
}
});
Маршрут:
import Route from '@ember/routing/route';
export default Route.extend({
queryParams: {
firstnameFilter: {
refreshModel: true
},
sort: {
refreshModel: true
}
},
model(params) {
if (params.firstnameFilter) {
params.filter = {};
params.filter['firstname'] = params.firstnameFilter;
delete params.firstnameFilter;
}
return this.get('store').query('contact', params);
}
});
Надеюсь, есть лучший способ!