在 laravel 分页中添加一些数据

Posted

技术标签:

【中文标题】在 laravel 分页中添加一些数据【英文标题】:Add some data in laravel paginate 【发布时间】:2017-04-23 09:26:38 【问题描述】:

正如标题所说,这是我的控制器

$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。 有什么想法吗?

【问题讨论】:

【参考方案1】:

您可以使用自定义数据手动创建集合并使用merge() helper:

$book = Data::where('userId','1')->paginate(3);

$custom = collect(['my_data' => 'My custom data here']);

$data = $custom->merge($book);

return response()->json($data);

刚刚检查过,效果很好。

【讨论】:

非常感谢!经过大量 array_merges 和失败的类型转换后的优雅解决方案【参考方案2】:

如果您“手动”使用Illuminate\Pagination\LengthAwarePaginator 类,则可以选择扩展它并覆盖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 需要做一些额外的工作,但它可以完成工作。

【讨论】:

最推荐的方式【参考方案3】:

分页函数将返回一个Illuminate\Pagination\LengthAwarePaginator类型的对象,不能只向它添加另一个字段。

我认为对您来说最好的解决方案是将分页对象和其他值添加到一个数组中,然后将该数组转换为 json。这样,您的图书数据就与您要添加的其他数据分开了。

像这样:

return response()->json([
    'books' => $books,
    'foo' => 'bar'
]);

在这种情况下,您的 json 对象将如下所示:


    books: 
        // Pagination object with books
    
    foo: 'bar'

【讨论】:

这样可以返回吗? response()->json($books); 是的,如果您事先制作数组并将其分配给$books。但它会是一样的。 好的,我看到了关键字“Illuminate\Pagination\LengthAwarePaginator,不能只添加另一个字段”。谢谢 对不起兄弟,我很感激你的回答,但@Alexey Mezenin 给出了我想要的最接近的答案。 :(【参考方案4】:

您还可以使用 eloquent 从模型中获取数据,例如,假设每个数据都有一个汽车、书籍和宠物的列表。您的数据模型文件应该有一个方法来声明与这些类的“有很多”关系,如下所示:

数据模型文件

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);

我希望这个替代方案对您或其他开发人员有用!

【讨论】:

【参考方案5】:

终于想通了。如果您尝试返回 json 或数组结果,只需先将分页数据更改为数组。然后将你需要的属性添加到数组中。

$results = $data->paginate()->toArray();
$results['new_attribute'] = 'Attribute Value';
return response()->json($result);

合并或附加到分页数据不起作用,因为当 json() 方法将其转换为数组时它会丢失。所以先把它转成数组,就可以修改最终结果了。

【讨论】:

【参考方案6】:

修改现有分页数据发送更新响应。

    $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()
            ]
        ]
    );

【讨论】:

【参考方案7】:

我相信正确的方法是创建一个资源(参见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;

您将获得包含元数据的正确响应,以及您在单独的“额外”属性中添加的数据。


 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: 

【讨论】:

【参考方案8】:
$book = Data::where('userId','1')->paginate(3); 
$book = $book->toArray();
$book['printWord'] = 'Hellow!';
return response()->json($book);

这会奏效。您可以将分页对象转换为数组,然后您需要将元素添加到数组中

【讨论】:

以上是关于在 laravel 分页中添加一些数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel 4 在分页中传递额外的参数?

在 Laravel 5.1 分页中使用漂亮的 URL

laravel 仅在分页中显示下一个和上一个链接

Laravel Livewire 在一页中进行多个分页

如何从 laravel 分页的第一页中删除查询字符串页面?

我想自学laraver,请诸位前辈给一些建议,谢谢