laravel - 从 Laravel ResourceCollection 从 vue/cli 中读取数据
问题描述
在 Laravel 6 后端 rest api 应用程序中,我使用 ResourceCollection 和 Resourcem 定义,例如:
<?php
namespace App\Http\Resources;
use App\Facades\MyFuncsClass;
use Illuminate\Http\Resources\Json\ResourceCollection;
class TaskCollection extends ResourceCollection
{
public function toArray($task)
{
return [
$this->collection->transform(function($task){
return [
'id' => $task->id,
'name' => $task->name,
'slug' => $task->slug,
...
'events' => !empty($task->events) ? $task->events : [],
'events_count' => !empty($task->events_count) ? $task->events_count : 0,
'created_at' => $task->created_at,
'updated_at' => $task->updated_at,
];
}),
];
}
public function with($task)
{
return [
'meta' => [
'version'=>MyFuncsClass::getAppVersion()
]
];
}
}
我在 Laravel 5.5 API resources for collections (standalone data)中找到了这个决定
它对我有用,但我不喜欢我在客户端部分获取数据的方式,因此对于 control 中定义的数据列表:
return (new TaskCollection($tasks));
我必须在 vue/cli app 中写:
axios.post(this.apiUrl + '/adminarea/tasks-filter', filters, this.credentialsConfig)
.then((response) => {
this.tasks = response.data.data[0]
this.tasks_total_count = response.data.meta.total
this.tasks_per_page = response.data.meta.per_page
当我需要获得我在 laravel 控件中定义的 1 个项目时:
return (new TaskCollection([$task])); // I have to wrap it as array
我必须在 vue/cli app 中写:
axios.get(this.apiUrl + '/adminarea/tasks/' + this.task_id, this.credentialsConfig)
.then((response) => {
// console.log('response::')
// console.log(response)
//
this.taskRow = response.data.data[0][0]
我不喜欢 data.data[0] 和 data.data[0][0] 这样的语法,甚至对我有用
在我的 app/Providers/AppServiceProvider.php 我有几行:
<?php
namespace App\Providers;
use Auth;
use Validator;
use Illuminate\Http\Resources\Json\Resource;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Resource::withoutWrapping(); // looks like that does not work for ResourceCollection!
<?php
namespace App\Providers;
use Auth;
use Validator;
use Illuminate\Http\Resources\Json\Resource;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Resource::withoutWrapping();
...
如果有办法摆脱 vue/cli 部分中的 data.data[0] 和 data.data[0][0] ?
修改 2: 我创建了几个列的新资源 app/Http/Resources/Skill.php :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Skill extends JsonResource
{
public static $wrap = 'skills';
public function toArray($request)
{
return [
'id' => $request->id,
'name' => $request->name,
'user_id' => $request->user_id,
'user_name' => $request->user_name,
'skill_id' => $request->skill_id,
'skill_name' => $request->skill_name,
'rating' => $request->rating,
'created_at' => $request->created_at,
];
}
}
和 app/Http/Resources/SkillCollection.php :
<?php
namespace App\Http\Resources;
use App\Facades\MyFuncsClass;
use App\Http\Resources\Skill;
use Illuminate\Http\Resources\Json\ResourceCollection;
class SkillCollection extends ResourceCollection
{
public static $wrap = 'skills';
public function toArray($request)
{
return $this->collection->transform(function($request){
parent::toArray($request);
});
}
结果我有空的“技能”:[null,null,null,null] 结果。怎么了 ?
谢谢!
解决方案
axios.get(this.apiUrl + '/adminarea/tasks/' + this.task_id, this.credentialsConfig)
.then(({ data }) => {
this.taskRow = data.data[0][0]
所以现在response.data.data[0][0]
缩短为data.data[0][0]
.
- 您可以做的第二件事是,在
toArray
您的类的函数中TaskCollection
,直接返回转换后的集合,而不是将其包装在数组中:
public function toArray($task)
{
return $this->collection->transform(function($task){
return [
'id' => $task->i
...
];
});
}
现在你不需要[0]
到处使用了。因此,您可以使用 代替data.data[0][0]
访问单个任务data.data[0]
。
- 为了避免必须使用
[0]
单数响应,您应该返回 aJsonResource
而不是 aResourceCollection
。为此,您需要将代码从内部移动$this->collection->transform
到新JsonResource
类。例如:
app/Http/Resources/TaskResource.php
:
<?php
namespace App\Http\Resources;
use App\Facades\MyFuncsClass;
use Illuminate\Http\Resources\Json\JsonResource;
class TaskResource extends JsonResource
{
public function toArray($task)
{
return [
'id' => $this->id,
'name' => $this->name,
'slug' => $this->slug,
...
];
}
public function with($task)
{
return [
'meta' => [
'version'=>MyFuncsClass::getAppVersion()
]
];
}
}
然后你可以返回一个资源
return new TaskResource($task);
在 Javascript 中,您现在可以完成一项任务data.data
:
axios.get(this.apiUrl + '/adminarea/tasks/' + this.task_id, this.credentialsConfig)
.then(({ data }) => {
this.taskRow = data.data;
您可以重构您的TaskCollection
类以隐式地TaskResource
为每个任务使用您的新类:
<?php
namespace App\Http\Resources;
use App\Facades\MyFuncsClass;
use Illuminate\Http\Resources\Json\ResourceCollection;
class TaskCollection extends ResourceCollection
{
public function toArray($request)
{
return parent::toArray($request);
}
public function with($task)
{
return [
'meta' => [
'version'=>MyFuncsClass::getAppVersion()
]
];
}
}
- 就像我试图在评论中解释的那样,在从函数
'data'
返回非空值时,您将无法避免将结果包装在一个键(如)中。with
如果您不相信我,请暂时删除您的with
功能,您会发现您只需使用data
(如果您禁用了包装Resource::withoutWrapping();
)即可访问您的任务。
但是,您可以做的一件事是自定义“换行”键。例如,对于您可能希望的任务集合,tasks
对于单个任务,只需task
. 您可以简单地为您的和类添加一个$wrap
属性:TaskCollection
TaskResource
class TaskCollection extends ResourceCollection
{
public static $wrap = 'tasks';
...
class TaskResource extends JsonResource
{
public static $wrap = 'task';
现在,您将能够使用 Javascript 访问任务列表,data.tasks
以及使用以下命令访问单个任务data.task
:
axios.post(this.apiUrl + '/adminarea/tasks-filter', filters, this.credentialsConfig)
.then(({ data }) => {
this.tasks = data.tasks;
axios.get(this.apiUrl + '/adminarea/tasks/' + this.task_id, this.credentialsConfig)
.then(({ data }) => {
this.taskRow = data.task;
推荐阅读
- android - 带有进度条的按钮 android
- c++ - C ++试图计算用户输入特定数字的次数
- svg - 在机车滚动中使用数据滚动的 SVG 路径动画
- soap - org.apache.cxf.interceptor.Fault:解组错误:意外元素(但适用于第 7 次调用)
- javascript - 为什么我将 for 循环代码转换为 while 循环代码失败了?
- rightnow-crm - 在本地服务 Oracle 服务云客户门户?
- oauth - Openid - 有没有办法在没有重定向的情况下获取由 Challenge 方法生成的状态和随机数?
- html - 将图像添加到 div 会移动周围的 div
- c# - 如何解析json并将其反序列化为类的ObservableCollection
- javascript - 递增字符串中包含的特定数字