laravel - Laravel 分页追加属性
问题描述
我正在从 php 重建我的搜索功能到 vue。
在 php 中,我曾经为我的模型类添加属性,例如 html 标签、缩略图等。我可以抓住它$model->HtmlThumb
并加载属性。现在,由于我收到了 json 响应,因此标签不存在。我知道我可以简单地使用$appends
模型类的属性。
问题是属性总是被附加,这是我绝对不想要的。
我知道我可以使用 hideAttributes 或类似的东西手动隐藏这些属性,但在现有应用程序中这样做并不方便。
这样它应该可以工作,但现在它返回一个项目数组而不是分页器集合。
$results = $db_query->paginate($num_of_results)->appends($result)->each(function($project){
$result->setAppends([
'ProjectDescription',
'FileCountLabel',
]);
});
我正在寻找一种方法来正确地做到这一点。
解决方案
OP 接受的答案是正确且有效的,但我想提出一个具有两个优点的替代答案:
它不必为每种模型类型和附加属性的每种组合创建一个新的 ResourceCollection。
来自分页器的响应的格式将与来自响应的格式相同
$db_query->paginate($num_of_results)
(默认情况下,ResourceCollection 将分页元数据移动到响应中的两个子对象中,links
并且meta
,这意味着需要重构使用 API 的代码)。
我们的想法是创建一个通用的 ResourceCollection,它允许我们动态控制附加的属性:
app/Resources/AppendablePaginator.php
<?php
namespace App\Http\Resources;
use Illuminate\Support\Arr;
use Illuminate\Http\Resources\Json\PaginatedResourceResponse;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Pagination\AbstractPaginator;
class AppendablePaginator extends ResourceCollection
{
private $appends = [];
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection->each->append($this->appends)
];
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function toResponse($request)
{
return $this->resource instanceof AbstractPaginator
? (new FlattenedPaginatedResourceResponse($this))->toResponse($request)
: parent::toResponse($request);
}
/**
* Append to the underlying models
* @param array|string|null $key
*/
public function modelAppend($key) {
if (is_null($key)) {
return $this;
}
if (is_array($key)) {
$this->appends = array_merge($this->appends, $key);
} else {
$this->appends[] = $key;
}
return $this;
}
}
class FlattenedPaginatedResourceResponse extends PaginatedResourceResponse {
/**
* Add the pagination information to the response.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function paginationInformation($request)
{
$paginated = $this->resource->resource->toArray();
return Arr::except($paginated, ['data']);
}
}
现在我们可以动态追加:
$results = (new AppendablePaginator($db_query->paginate($num_of_results))->modelAppend([
'ProjectDescription',
'FileCountLabel'
]);
这意味着我们可以轻松地更改附加属性,并且由于此代码适用于任何模型类型,我们不必担心生成新集合。
推荐阅读
- python - 使用 youtube-dl 录制实时流时,我应该在哪里设置录制的持续时间?
- django - 如何使用单个日期查询 Postgres DateRange?
- python - 如何使用 plotly 为股票数据生成线条动画?
- rust - 我可以仅为调试配置文件激活依赖项功能吗?
- c# - WinForm C#如何将方法附加到以编程方式创建的控件
- javascript - React 在每个函数之后运行一个特定的函数
- python - 如何提高神经网络在地标检测和识别中的准确性?
- http - Kubernetes 入口启用 Http2
- c# - 我的 SqlException 的原因是什么:'=' 附近的语法不正确?
- reactjs - 有人可以告诉我如何在本机反应中将formik中的handleChange和handleSubmit功能从父组件传递到子组件