[扩展推荐] Laravel 视图模型辅助类
由 Spatie 的 Brent Roose 设计的 Laravel View Models 是一个让你可以把在控制器中做的工作移动到一个“视图模型”的包:
你是不是曾经在控制器中写一大堆代码,只为了给视图提供各种变量?现在,你可以将那些逻辑交给所谓的视图模型。其实,视图模型就是一个简单的类,接收一些数据,然后将其转换为视图所需要的变量。
一个视图模型被设计为存放视图相关的复杂逻辑,并且把这些逻辑从控制器中移出来:
class PostViewModel extends ViewModel
{
public $indexUrl = null;
public function __construct(User $user, Post $post = null)
{
$this->user = $user;
$this->post = $post;
$this->indexUrl = action([PostsController::class, 'index']);
}
public function post(): Post
{
return $this->post ?? new Post();
}
public function categories(): Collection
{
return Category::canBeUsedBy($this->user)->get();
}
}
上面定义的视图模型类在控制器中创建:
class PostsController
{
public function create()
{
$viewModel = new PostViewModel(
current_user()
);
return view('blog.form', $viewModel);
}
public function edit(Post $post)
{
$viewModel = new PostViewModel(
current_user(),
$post
);
return view('blog.form', $viewModel);
}
}
同时,该视图模型和控制器提供给视图下面这些能力:
<input type="text" value="{{ $post->title }}" />
<input type="text" value="{{ $post->body }}" />
<select>
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach
</select>
<a href="{{ $indexUrl }}">Back</a>
所有视图模型中的公共方法和属性都可以在视图中使用。
我认为这个包是对于这种逻辑的极好的抽象,你可以像下面这样直接返回一个视图,而不是返回整个视图模型:
class PostsController
{
public function update(Request $request, Post $post)
{
// ...
return (new PostViewModel($post))->view('post.form');
}
}
不仅如此,你还可以对外暴露带参数的函数:
class PostViewModel extends ViewModel
{
public function formatDate(Carbon $date): string
{
return $date->format('Y-m-d');
}
}
然后在模板中引用它:
{{ $formatDate($post->created_at) }}
多亏了 Brent Roose 以及 Spatie 的人们为此做出的贡献!你可以 从 Gtihub spatie/laravel-view-models 获取其源代码和安装指南。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
反射运用得炉火纯青
感觉 View Model 这个包像是 Api 开发中 Laravel Resource 和 Dingo Transformers,用来专门格式化数据,处理变量。