Из того, что я прочитал, нумерация страниц Laravel работает не так, как ожидалось.Моя библиотека внешнего интерфейса (Kendo) использует take
и skip
для управления нумерацией страниц.
На бэкэнде легко построить ответ:
$builder = Model::query();
$builder->where(...); // If any conditions
return [
'total' => $builder->count(),
'data' => $builder
->take(request('take'))
->skip(request('skip'))
->get()
->toArray()
]
Если я использую paginate
, я могу упростить это написание, но я больше не буду совместим с моим интерфейсом,
Как я могу упростить это до чего-то вроде:
return Model::where(...)->withKendoPaging()->get()->toKendoJson()
Я могу легко написать macro
для Collection
, который строит ответ [total: 1, data: [...]]
, и один для Builder
, которыйдобавляет skip
/ take
на основе текущего request
.К сожалению, я не нашел способа получить total
до where
, и моя текущая реализация работает так:
$builder = Model::query();
$total = $builder->count();
$builder
->where(...)
->withKendoPaging->get()
->toKendoArray($total)
Я хотел бы найти более элегантный способ написать этот другойчем переопределение всей структуры Illuminate (Builder, Collection, App, ...)
Один из возможных способов - добавить значение для построителя с помощью:
Builder::macro('kendoPaging', function($pager = []) {
// Keep track of the total before paging
$this->totalCount = $this->count();
// Do the paging
$skip = array_get($pager, 'skip', request('skip', 0));
$take = array_get($pager, 'take', request('take'));
if ($skip > 0) {
$builder = $builder->skip($skip);
}
if ($take > 0) {
$builder = $builder->take($take);
}
}
Тогда я должен найтиспособ передать это значение totalCount
от застройщика в коллекцию.Этого можно добиться с помощью уродливой уловки:
Config::set('kendo.totalCount', $this->count)