屏幕状态
建议编辑在 PHP 中,当我们想要在请求之间存储中间结果时,通常会使用数据库(如 MySQL)或快速存储系统(如 Redis)等存储解决方案。对于更简单的情况,我们可以直接在 URL 中传递状态。你可能见过这样的例子,例如 operation?result=success
。这些方法都适用且广泛应用。
然而,在 Laravel Orchid 中,有一个方便的解决方案可以存储少量信息,比如一个 Eloquent 模型。这是可能的,因为每个请求都会携带屏幕所有公共属性的状态。
让我们尝试创建一个名为 StateScreen
的新屏幕,使用 Artisan 命令:
php artisan orchid:screen StateScreen
接下来,我们需要在路由文件中注册它:
use App\Orchid\Screens\StateScreen;
Route::screen('state', StateScreen::class)->name('state');
一个经典的例子是计数点击次数。让我们在新创建的屏幕中添加以下代码:
<?php
namespace App\Orchid\Screens;
use Illuminate\Http\Request;
use Orchid\Screen\Screen;
use Orchid\Support\Color;
use Orchid\Screen\Fields\Label;
use Orchid\Screen\Actions\Button;
use Orchid\Support\Facades\Layout;
class StateScreen extends Screen
{
/**
* 获取要在屏幕上显示的数据。
*
* @return array
*/
public function query(): array
{
return [
'clicks' => 0,
];
}
/**
* 屏幕在头部显示的名称。
*
* @return string|null
*/
public function name(): ?string
{
return 'State';
}
/**
* 屏幕的布局元素。
*
* @return array
*/
public function layout(): array
{
return [
Layout::rows([
Label::make('clicks')->title('点击次数:'),
]),
];
}
}
让我们在浏览器中打开页面,看看屏幕的样子。它应该显示标签 “点击次数: 0”。现在,让我们在屏幕上添加一个简单的方法来查看请求内容:
/**
* 屏幕的布局元素。
*
* @return array
*/
public function layout(): array
{
return [
Layout::rows([
Label::make('clicks')
->title('点击次数:'),
Button::make('增加点击')
->type(Color::DARK)
->method('increment'),
]),
];
}
/**
* 增加点击次数。
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function increment(Request $request)
{
dd($request->all());
}
点击 “提交” 按钮后,你将看到请求内容。然而,请注意点击次数的值缺失。在传统的服务器应用程序中,我们可以通过添加一个隐藏的表单字段 <input type="hidden">
并使用 GET 参数 ?count=1
进行重定向来实现这一点。
幸运的是,Orchid 提供了一个方便的解决方案,可以自动保存屏幕公共属性的状态。
class StateScreen extends Screen
{
/**
* 点击次数。
*
* @var int
*/
public $clicks;
//...
/**
* 增加点击次数。
*
* @return \Illuminate\Http\RedirectResponse
*/
public function increment(Request $request)
{
dd($this->clicks);
}
}
现在,当我们提交表单时,属性值将被保留。在这个例子中,我们使用了一个简单的 int
类型,但它也可以用于更复杂的对象,如 Eloquent 模型。
在公共屏幕属性中存储大量数据可能会导致性能问题。因此,建议谨慎操作,避免在公共属性中存储过多信息。
要更新屏幕状态,我们只需修改公共属性即可。但在此之前,让我们更新 query
方法以返回一个包含键 clicks
的数组,其中包含属性的当前值。如果缺失,我们将其设置为 0
:
class StateScreen extends Screen
{
/**
* 点击次数。
*
* @var int
*/
public $clicks;
/**
* 获取要在屏幕上显示的数据。
*
* @return array
*/
public function query(): array
{
return [
'clicks' => $this->clicks ?? 0,
];
}
}
让我们更新 increment()
方法,使其每次调用时将 clicks
属性的值增加一。
/**
* 增加点击次数。
*/
public function increment()
{
$this->clicks++;
}
现在,当用户点击 “增加点击” 按钮时,点击计数器将被更新。如果你刷新页面,计数器将被重置。