bakle / crud-core
Laravel Crud 核心文件
1.2.0
2024-01-14 22:27 UTC
Requires
- php: ^8.2
- laravel/framework: ^10.0
Requires (Dev)
- orchestra/testbench: ^8.10
- phpunit/phpunit: ^10.1
This package is auto-updated.
Last update: 2024-09-15 00:07:34 UTC
README
此包包含所有创建 CRUD 所需的样板逻辑的基础文件。
安装
composer require bakle/crud-core
此包中包含什么内容?
UrlPresenter
URL 展示器封装了在 Route::resource('users, UserController::class)
中生成的路由
对于单个模型
class UserUrlPresenter extends BaseUrlPresenter { function getRouteName(): string { return 'users'; } } // --- Examples --- // Url presenter for routes that doesn't depend on a specific model (index, create) $userUrlPresenter = new UserUrlPresenter(); $userUrlPresenter->index(); // --> /users $userUrlPresenter->create(); // --> /users/create $userUrlPresenter->store(); // --> /users (for post method) // Url presenter for routes that depend on a specific model (show, edit, update, delete ) $user = User::first(); $userUrlPresenter = new UserUrlPresenter($user); $userUrlPresenter->index(); // --> /users $userUrlPresenter->show(); // --> /users/1 $userUrlPresenter->create(); // --> /users/create $userUrlPresenter->store(); // --> /users (for post method) $userUrlPresenter->edit(); // --> /users/1/edit $userUrlPresenter->update(); // --> /users/1 $userUrlPresenter->destroy(); // --> /users/1
对于相关模型
class UserPostCommentUrlPresenter extends BaseUrlPresenter { function getRouteName(): string { return 'users.posts.comments'; } } class Post extends \Illuminate\Database\Eloquent\Model { public function getRouteKeyName(): string { return 'slug'; } } // Example $user = User::first(); $post = Post::first(); $comment = Comment::first(); $urlPresenter = new UserPostCommentUrlPresenter($user, $post, $comment); $userUrlPresenter->index(); // --> /users/1/posts/the-post-slug/comments $userUrlPresenter->show(); // --> /users/1/posts/the-post-slug/comments/1 $userUrlPresenter->create(); // --> /users/1/posts/the-post-slug/comments/create $userUrlPresenter->store(); // --> /users/1/posts/the-post-slug/comments (for post method) $userUrlPresenter->edit(); // --> /users/1/posts/the-post-slug/comments/1/edit $userUrlPresenter->update(); // --> /users/1/posts/the-post-slug/comments/1 $userUrlPresenter->destroy(); // --> /users/1/posts/the-post-slug/comments/1
实体
实体是一个额外的层,用于包装你的模型并添加额外的逻辑。BaseEntity
仅需要实现 url()
方法
class UserEntity extends BaseEntity { public function url(): ?BaseUrlPresenter { return new UserUrlPresenter($this->model); } ... // more methods } // Example single model $user = User::first(); $userEntity = new UserEntity($user); $user->entity->getCreatedAtDayDateFormat(); // Sat, Oct 7, 2023 // Example multiple model $users = User::all(); $userEntities = UserEntity::collection($users); $userEntities->first()->url()->show() // /users/1
视图模型
视图模型封装了你需要发送到视图的所有逻辑和数据。
IndexViewModel
此视图模型发送以下数据到视图:
- entities: 模型定义在
IndexViewModel
中的实体集合(即:UserEntity) - 分页: 由于现在你接收的是实体集合而不是模型,这相当于执行
$users->links
。现在你可以这样做<div class="flex w-full mt-4 justify-end"> {!! $pagination !!} </div>
- 标题: 这只是你在
getTitle()
方法中返回的字符串。在索引中很有用,可以在 blade 中添加,如下所示
<h1 class="text-2xl">{{ $title }}</h1>
示例
class UserIndexViewModel extends BaseIndexViewModel { public function getTitle(): string { return trans('Users'); } public function getEntityClass(): string { return UserEntity::class; } } // In the UserController class UserController extends Controller { public function index(Request $request): View { $users = User::query()->with('roles'); return view('users.index', (new UserIndexViewModel($users, $request))->build() ); } }
ShowViewModel
此视图模型发送以下数据到视图:
- entity: 模型定义在
ShowViewModel
中的单个实体(即:UserEntity)
示例
class UserShowViewModel extends BaseShowViewModel { public function getTitle(): string { return trans('User'); } public function getEntityClass(): string { return UserEntity::class; } protected function getExtraData(): array { return [ 'title' => $this->getTitle() ]; } } // In your UserController class UserController extends Controller { public function show(User $user) { $user->load('roles'); return view('users.show', (new UserShowViewModel($user))->build()); } }
FormViewModel
此视图模型发送以下数据到视图:
- entity: 模型定义在
ShowViewModel
中的单个实体(即:UserEntity) - 表单: 这包含提交表单的 URL、方法类型(POST 或 PUT)和一些其他辅助方法。在表单中很有用,如下所示
<form method="POST" action="{{ $form->getUrl() }}">
@csrf
@method($form->getMethod())
//...your fields
<button class="btn btn-primary">
@if($form->isEditType())
{{ trans('Update') }}
@else
{{ trans('Create') }}
@endif
</button>
</form>
- 标题: 这将自动解析标题,基于方法类型。例如,如果你使用
->setFormType(FormTypes::CREATE)
,标题将是 创建用户,如果你使用->setFormType(FormTypes::EDIT)
,标题将是 编辑用户。你可以这样使用它
<h1 class="text-2xl">{{ $title }}</h1>
示例
class UserFormViewModel extends BaseFormViewModel { protected function getEntityClass(): string { return UserEntity::class; } protected function getExtraData(): array { return [ 'roles' => Role::query()->get(); ]; } } // In your UserController class UserController extends Controller { public function create(): View { return view('users.form', (new UserFormViewModel(new User()))->setFormType(FormTypes::CREATE)->build() ); } public function edit(User $user): View { return view('users.form', (new UserFormViewModel($user))->setFormType(FormTypes::EDIT)->build() ); } }
所有 ViewModel
都包含一个 getExtraData()
方法,你可以返回一个数组,其中包含你需要发送到视图的额外数据。