简体   繁体   English

在 laravel 分页中添加一些数据

[英]Add some data in laravel paginate

As the tittle said, Here is my Controller正如标题所说,这是我的控制器

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

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

And get the json data like this:并像这样获取 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? 

I tried to do this :我试图这样做:

$book = Data::where('userId','1')->paginate(3);
$book->printWord = 'Hellow!';
return response()->json($book);

But, It seem will remove the column printWord .但是,它似乎会删除列printWord Any idea?任何的想法?

You can create collection with custom data manually and use merge() helper:您可以手动使用自定义数据创建集合并使用merge()助手:

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

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

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

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

Just checked, it works just fine.刚刚检查,它工作得很好。

If you use the Illuminate\\Pagination\\LengthAwarePaginator class "manually", there's the option of extending it and overriding the toArray method:如果您“手动”使用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;
    }
};

Result结果

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

There's some extra work involved with instantiating LengthAwarePaginator yourself, but it gets the job done.自己实例化LengthAwarePaginator一些额外的工作,但它可以完成工作。

The paginate function will return an object of the type Illuminate\\Pagination\\LengthAwarePaginator , it is not possible to just add another field to this. paginate 函数将返回一个Illuminate\\Pagination\\LengthAwarePaginator类型的对象,不可能只向它添加另一个字段。

I think the best solution for you would be to add the pagination object and the other values in an array and convert this array to json.我认为最适合您的解决方案是在数组中添加分页对象和其他值,然后将此数组转换为 json。 This way your books data is seperated from the other data you want to add.这样,您的图书数据就与您要添加的其他数据分开了。

Like so:像这样:

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

In this case your json object will look like this:在这种情况下,您的 json 对象将如下所示:

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

You can also obtain data from your model using eloquent, for example, let say that each Data has a list of cars, books, and pets.您还可以使用 eloquent 从模型中获取数据,例如,假设每个数据都有一个汽车、书籍和宠物的列表。 Your Data model file should have a method that declares the "has many" relations with those classes, like below:您的数据模型文件应该有一个方法来声明与这些类的“有很多”关系,如下所示:

Data model file数据模型文件

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

Also, you must have the "belongsTo" method in every Car, Book, and Pet model.此外,您必须在每个 Car、Book 和 Pet 模型中都有“belongsTo”方法。

Car model file汽车模型文件

...
public function data(){
    return $this->belongsTo(Data::class);
}
...

Finally, to obtain your results paginated and with all the data related to cars, books, and pets, the implementation should be:最后,要获得分页的结果以及与汽车、书籍和宠物相关的所有数据,实现应该是:

Method in your Controller控制器中的方法

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

foreach($data_elements as $d){
    $d->cars;
    $d->books;
    $d->pets;
}

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

I hope this alternative be useful for you or for some other developer!我希望这个替代方案对您或其他开发人员有用!

Finally figured this out.终于想通了这一点。 If you are trying to return a json or array result, just change the paginated data to an array first.如果您尝试返回 json 或数组结果,只需先将分页数据更改为数组。 Then add the attributes you need to the array.然后将您需要的属性添加到数组中。

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

Merging or appending to the paginated data doesn't work because it gets lost when the json() method converts it to an array.合并或附加到分页数据不起作用,因为当 json() 方法将其转换为数组时它会丢失。 So by converting it to an array first, you can modify the end results.因此,通过先将其转换为数组,您可以修改最终结果。

Modify exiting pagination data send update response.修改现有分页数据发送更新响应。

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

I believe the proper way is to create a resource (see https://laravel.com/docs/8.x/eloquent-resources ) and use the additional() method for this.我相信正确的方法是创建一个资源(参见https://laravel.com/docs/8.x/eloquent-resources )并为此使用 additional() 方法。 A common use case is displaying a paged result set while showing the grand total for the entire collection.一个常见的用例是显示分页结果集,同时显示整个集合的总计。

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

You'll get the proper response with metadata, and your added data in the separate 'extra' property.您将获得正确的元数据响应,以及在单独的“额外”属性中添加的数据。

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

This will work.这将起作用。 you can convert paginate object to array, then you need to add element into the array您可以将分页对象转换为数组,然后您需要将元素添加到数组中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM