在 laravel 分页中添加一些数据
Add some data in laravel paginate
正如标题所说,这是我的控制器
$book = Data::where('userId','1')->paginate(3);
return response()->json($book);
并像这样获取 json 数据:
data:[{id: 1, userId: 1, vendorId: 1, name: "Alfreda Berge PhD", phone: "1-850-813-5950 x96169",…},…]
from:1
last_page:2
next_page_url: "http:/localhost/XX/public/user/book/list/1?page=2"
perpage:4
prev_page_url:null
to:4
total:5
// if I want to add a new column and value here ,what should I do?
我试过这样做:
$book = Data::where('userId','1')->paginate(3);
$book->printWord = 'Hellow!';
return response()->json($book);
但是,似乎会删除列 printWord
。
有什么想法吗?
paginate 函数将 return 类型为 Illuminate\Pagination\LengthAwarePaginator
的对象,不可能只向其添加另一个字段。
我认为最适合您的解决方案是将分页对象和其他值添加到一个数组中,并将该数组转换为 json。这样您的图书数据就与您要添加的其他数据分开了。
像这样:
return response()->json([
'books' => $books,
'foo' => 'bar'
]);
在这种情况下,您的 json 对象将如下所示:
{
books: {
// Pagination object with books
}
foo: 'bar'
}
您可以手动创建包含自定义数据的集合并使用 merge()
帮助程序:
$book = Data::where('userId','1')->paginate(3);
$custom = collect(['my_data' => 'My custom data here']);
$data = $custom->merge($book);
return response()->json($data);
刚刚检查,它工作正常。
您还可以使用 eloquent 从您的模型中获取数据,例如,假设每个数据都有一个汽车、书籍和宠物的列表。您的数据模型文件应该有一个方法来声明 "has many" 与那些 类 的关系,如下所示:
数据模型文件
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Data extends Model{
protected $table = 'data';
protected $fillable = [
'id', 'user_id', 'vendorId', 'name', 'phone'
];
public function cars(){
return $this->hasMany(Car::class);
}
public function books(){
return $this->hasMany(Book::class);
}
public function pets(){
return $this->hasMany(Pet::class);
}
此外,您必须在每个 Car、Book 和 Pet 模型中使用 "belongsTo" 方法。
车模文件
...
public function data(){
return $this->belongsTo(Data::class);
}
...
最后,要获得分页的结果以及与汽车、书籍和宠物相关的所有数据,实施应该是:
控制器中的方法
$data_elements = Data::where('userId','1')->paginate(3);
foreach($data_elements as $d){
$d->cars;
$d->books;
$d->pets;
}
return response()->json($data_elements);
我希望这个替代方案对您或其他开发人员有用!
如果您使用 Illuminate\Pagination\LengthAwarePaginator class "manually",可以选择扩展它并覆盖 toArray
方法:
return new class(
$collection,
$count,
$limit,
$page,
// https://github.com/laravel/framework/blob/6.x/src/Illuminate/Pagination/LengthAwarePaginator.php#L40
// values here will become properties of the object
[
'seed' => $seed
]
) extends LengthAwarePaginator {
public function toArray()
{
$data = parent::toArray();
// place whatever you want to send here
$data['seed'] = $this->seed;
return $data;
}
};
结果
current_page 1
data []
first_page_url "/finder?max_miles=100&zip_code=10001&seed=0.2&page=1"
from null
last_page 1
last_page_url "/finder?max_miles=100&zip_code=10001&seed=0.2&page=1"
next_page_url null
path "/finder"
per_page 20
prev_page_url null
to null
total 0
seed 0.2 // <-- our custom prop
自己实例化 LengthAwarePaginator
涉及一些额外的工作,但它完成了工作。
终于明白了。如果您尝试 return json 或数组结果,只需先将分页数据更改为数组即可。然后将你需要的属性添加到数组中。
$results = $data->paginate()->toArray();
$results['new_attribute'] = 'Attribute Value';
return response()->json($result);
合并或附加到分页数据不起作用,因为当 json() 方法将其转换为数组时它会丢失。所以先转成数组,可以修改最终结果。
修改现有分页数据发送更新响应。
$itemsPaginated = $this->items()
->paginate(15);
$itemsTransformed = $itemsPaginated
->getCollection()
->map(function($item) {
return [
'id' => $item->id,
];
})->toArray();
$itemsTransformedAndPaginated = new \Illuminate\Pagination\LengthAwarePaginator(
$itemsTransformed,
$itemsPaginated->total(),
$itemsPaginated->perPage(),
$itemsPaginated->currentPage(), [
'path' => \Request::url(),
'query' => [
'page' => $itemsPaginated->currentPage()
]
]
);
我认为正确的方法是创建资源(参见 https://laravel.com/docs/8.x/eloquent-resources)并为此使用 additional() 方法。一个常见的用例是显示分页结果集,同时显示整个集合的总计。
// collect the grand total
$grandTotal = $customer->invoices()->sum('amount_excl');
// prepare the result set
$data = InvoiceResource::collection($customer->invoices()->paginate(10));
// inject additional data
$data->additional(['extra'=>['total_amount' => $grandTotal]]);
return $data;
您将通过元数据和您添加的数据获得正确的响应 'extra' 属性。
{
data: [{id: 15922, identifier: "12345", amount_excl: 143.27,…},…]
extra: {total_amount: 6554.35}
links: {first: "https://your.url.com/customers/80/invoices?page=1",…}
meta: {current_page: 1, from: 1, last_page: 5, path:
}
$book = Data::where('userId','1')->paginate(3);
$book = $book->toArray();
$book['printWord'] = 'Hellow!';
return response()->json($book);
这会奏效。您可以将分页对象转换为数组,然后您需要将元素添加到数组中
正如标题所说,这是我的控制器
$book = Data::where('userId','1')->paginate(3);
return response()->json($book);
并像这样获取 json 数据:
data:[{id: 1, userId: 1, vendorId: 1, name: "Alfreda Berge PhD", phone: "1-850-813-5950 x96169",…},…]
from:1
last_page:2
next_page_url: "http:/localhost/XX/public/user/book/list/1?page=2"
perpage:4
prev_page_url:null
to:4
total:5
// if I want to add a new column and value here ,what should I do?
我试过这样做:
$book = Data::where('userId','1')->paginate(3);
$book->printWord = 'Hellow!';
return response()->json($book);
但是,似乎会删除列 printWord
。
有什么想法吗?
paginate 函数将 return 类型为 Illuminate\Pagination\LengthAwarePaginator
的对象,不可能只向其添加另一个字段。
我认为最适合您的解决方案是将分页对象和其他值添加到一个数组中,并将该数组转换为 json。这样您的图书数据就与您要添加的其他数据分开了。
像这样:
return response()->json([
'books' => $books,
'foo' => 'bar'
]);
在这种情况下,您的 json 对象将如下所示:
{
books: {
// Pagination object with books
}
foo: 'bar'
}
您可以手动创建包含自定义数据的集合并使用 merge()
帮助程序:
$book = Data::where('userId','1')->paginate(3);
$custom = collect(['my_data' => 'My custom data here']);
$data = $custom->merge($book);
return response()->json($data);
刚刚检查,它工作正常。
您还可以使用 eloquent 从您的模型中获取数据,例如,假设每个数据都有一个汽车、书籍和宠物的列表。您的数据模型文件应该有一个方法来声明 "has many" 与那些 类 的关系,如下所示:
数据模型文件
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Data extends Model{
protected $table = 'data';
protected $fillable = [
'id', 'user_id', 'vendorId', 'name', 'phone'
];
public function cars(){
return $this->hasMany(Car::class);
}
public function books(){
return $this->hasMany(Book::class);
}
public function pets(){
return $this->hasMany(Pet::class);
}
此外,您必须在每个 Car、Book 和 Pet 模型中使用 "belongsTo" 方法。
车模文件
...
public function data(){
return $this->belongsTo(Data::class);
}
...
最后,要获得分页的结果以及与汽车、书籍和宠物相关的所有数据,实施应该是:
控制器中的方法
$data_elements = Data::where('userId','1')->paginate(3);
foreach($data_elements as $d){
$d->cars;
$d->books;
$d->pets;
}
return response()->json($data_elements);
我希望这个替代方案对您或其他开发人员有用!
如果您使用 Illuminate\Pagination\LengthAwarePaginator class "manually",可以选择扩展它并覆盖 toArray
方法:
return new class(
$collection,
$count,
$limit,
$page,
// https://github.com/laravel/framework/blob/6.x/src/Illuminate/Pagination/LengthAwarePaginator.php#L40
// values here will become properties of the object
[
'seed' => $seed
]
) extends LengthAwarePaginator {
public function toArray()
{
$data = parent::toArray();
// place whatever you want to send here
$data['seed'] = $this->seed;
return $data;
}
};
结果
current_page 1
data []
first_page_url "/finder?max_miles=100&zip_code=10001&seed=0.2&page=1"
from null
last_page 1
last_page_url "/finder?max_miles=100&zip_code=10001&seed=0.2&page=1"
next_page_url null
path "/finder"
per_page 20
prev_page_url null
to null
total 0
seed 0.2 // <-- our custom prop
自己实例化 LengthAwarePaginator
涉及一些额外的工作,但它完成了工作。
终于明白了。如果您尝试 return json 或数组结果,只需先将分页数据更改为数组即可。然后将你需要的属性添加到数组中。
$results = $data->paginate()->toArray();
$results['new_attribute'] = 'Attribute Value';
return response()->json($result);
合并或附加到分页数据不起作用,因为当 json() 方法将其转换为数组时它会丢失。所以先转成数组,可以修改最终结果。
修改现有分页数据发送更新响应。
$itemsPaginated = $this->items()
->paginate(15);
$itemsTransformed = $itemsPaginated
->getCollection()
->map(function($item) {
return [
'id' => $item->id,
];
})->toArray();
$itemsTransformedAndPaginated = new \Illuminate\Pagination\LengthAwarePaginator(
$itemsTransformed,
$itemsPaginated->total(),
$itemsPaginated->perPage(),
$itemsPaginated->currentPage(), [
'path' => \Request::url(),
'query' => [
'page' => $itemsPaginated->currentPage()
]
]
);
我认为正确的方法是创建资源(参见 https://laravel.com/docs/8.x/eloquent-resources)并为此使用 additional() 方法。一个常见的用例是显示分页结果集,同时显示整个集合的总计。
// collect the grand total
$grandTotal = $customer->invoices()->sum('amount_excl');
// prepare the result set
$data = InvoiceResource::collection($customer->invoices()->paginate(10));
// inject additional data
$data->additional(['extra'=>['total_amount' => $grandTotal]]);
return $data;
您将通过元数据和您添加的数据获得正确的响应 'extra' 属性。
{
data: [{id: 15922, identifier: "12345", amount_excl: 143.27,…},…]
extra: {total_amount: 6554.35}
links: {first: "https://your.url.com/customers/80/invoices?page=1",…}
meta: {current_page: 1, from: 1, last_page: 5, path:
}
$book = Data::where('userId','1')->paginate(3);
$book = $book->toArray();
$book['printWord'] = 'Hellow!';
return response()->json($book);
这会奏效。您可以将分页对象转换为数组,然后您需要将元素添加到数组中