表单回调
<h1>表单回调</h1>
<p><code>Form</code>目前提供了下面几个方法来接收回调函数:</p>
<h3>creating</h3>
<p>在新增页面调用(非提交操作)</p>
<pre><code class="language-php">$form-&gt;creating(function (Form $form) {
if (...) { // 验证逻辑
$form-&gt;responseValidationMessages('title', 'title格式错误');
// 如有多个错误信息,第二个参数可以传数组
$form-&gt;responseValidationMessages('content', ['content格式错误', 'content不能为空']);
}
});</code></pre>
<h3>editing</h3>
<p>在编辑页面调用(非提交操作)</p>
<pre><code class="language-php">$form-&gt;editing(function (Form $form) {
if (...) { // 验证逻辑
$form-&gt;responseValidationMessages('title', 'title格式错误');
// 如有多个错误信息,第二个参数可以传数组
$form-&gt;responseValidationMessages('content', ['content格式错误', 'content不能为空']);
}
});</code></pre>
<h3>submitted</h3>
<p>在表单提交前调用,在此事件中可以修改、删除用户提交的数据或者中断提交操作</p>
<pre><code class="language-php">$form-&gt;submitted(function (Form $form) {
// 获取用户提交参数
$title = $form-&gt;title;
// 上面写法等同于
$title = $form-&gt;input('title');
// 删除用户提交的数据
$form-&gt;deleteInput('title');
// 中断后续逻辑
return $form-&gt;response()-&gt;error('服务器出错了~');
});</code></pre>
<h3>saving</h3>
<p>保存前回调,在此事件中可以修改、删除用户提交的数据或者中断提交操作</p>
<pre><code class="language-php">$form-&gt;saving(function (Form $form) {
// 判断是否是新增操作
if ($form-&gt;isCreating()) {
}
// 删除用户提交的数据
$form-&gt;deleteInput('title');
// 中断后续逻辑
return $form-&gt;response()-&gt;error('服务器出错了~');
});</code></pre>
<h3>saved</h3>
<p>保存后回调,此事件新增和修改操作共用,通过第二个参数<code>$result</code>可以判断数据是否保存成功。</p>
<p>> {tip} 新增页面下,<code>$result</code>的值是新增记录的自增ID</p>
<pre><code class="language-php">$form-&gt;saved(function (Form $form, $result) {
// 判断是否是新增操作
if ($form-&gt;isCreating()) {
// 自增ID
$newId = $result;
// 也可以这样获取自增ID
$newId = $form-&gt;getKey();
if (! $newId) {
return $form-&gt;error('数据保存失败');
}
return;
}
// 修改操作
});</code></pre>
<p>> {tip} <code>$form-&gt;repository()-&gt;eloquent()</code>為當前新增或編輯後的eloquent</p>
<pre><code class="language-php">$form-&gt;saved(function (Form $form, $result) {
// 在表單保存後獲取eloquent
$form-&gt;repository()-&gt;eloquent()-&gt;update(['data' =&gt; 'new']);
});</code></pre>
<h3>deleting</h3>
<p>删除前回调</p>
<pre><code class="language-php">$form-&gt;deleting(function (Form $form) {
// 获取待删除行数据,这里获取的是一个二维数组
$data = $form-&gt;model()-&gt;toArray();
});</code></pre>
<h3>deleted</h3>
<p>删除后回调,通过第二个参数<code>$result</code>可以判断数据是否删除成功。</p>
<pre><code class="language-php">$form-&gt;deleted(function (Form $form, $result) {
// 获取待删除行数据,这里获取的是一个二维数组
$data = $form-&gt;model()-&gt;toArray();
// 通过 $result 可以判断数据是否删除成功
if (! $result) {
return $form-&gt;response()-&gt;error('数据删除失败');
}
// 返回删除成功提醒,此处跳转参数无效
return $form-&gt;response()-&gt;success('删除成功');
});</code></pre>
<h3>uploading</h3>
<p>图片、文件上传事件</p>
<p>> {tip} 文件上传是一个独立的api请求,这个事件内<code>redirect</code>方法是无效的。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
use Dcat\Admin\Form\Field;
use Dcat\Admin\Contracts\UploadField as UploadFieldInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
$form-&gt;uploading(function (Form $form, UploadFieldInterface $field, UploadedFile $file) {
// $file 即是当前上传的完整文件
/* @var Field $field */
// 获取文件上传字段名称
$column = $field-&gt;column();
});</code></pre>
<h3>uploaded</h3>
<p>图片、文件上传完毕事件</p>
<p>> {tip} 文件上传是一个独立的api请求,这个事件内<code>redirect</code>方法是无效的。</p>
<pre><code class="language-php">use Dcat\Admin\Form;
use Dcat\Admin\Form\Field;
use Dcat\Admin\Contracts\UploadField as UploadFieldInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
$form-&gt;uploaded(function (Form $form, UploadFieldInterface $field, UploadedFile $file, $response) {
// $file 即是当前上传的完整文件
/* @var Field $field */
// 获取文件上传字段名称
$column = $field-&gt;column();
$response = (array) $response-&gt;getData();
// 文件上传成功
if ($response['status']) {
// 文件访问地址
$url = $response['url'];
}
});</code></pre>
<h3>获取模型中的数据</h3>
<pre><code class="language-php">$form-&gt;saved(function (Form $form) {
$id = $form-&gt;getKey();
$username = $form-&gt;model()-&gt;username;
// 获取最终保存的数组
$updates = $form-&gt;updates();
});</code></pre>
<h3>修改或删除用户提交的数据</h3>
<p>此功能在<code>saving</code>和<code>submitted</code>事件中有效</p>
<pre><code class="language-php">$form-&gt;select('author_id');
$form-&gt;saving(function (Form $form) {
// 修改用户提交的数据
$form-&gt;author_id = 1;
// 删除、忽略用户提交的数据
$form-&gt;deleteInput('author_id');
});</code></pre>
<h3>修改模型中的数据</h3>
<p>修改模型中的数据需要配合隐藏表单使用。举例:</p>
<pre><code class="language-php">$form-&gt;hidden('author_id');
$form-&gt;saving(function (Form $form) {
$form-&gt;author_id = 1;
});</code></pre>
<h3>表单响应</h3>
<p>> {tip} 此方法在<code>creating</code>、<code>editing</code>事件中均不可用。</p>
<p>详细用法请参考文档 <a href="response.md">动作和表单响应</a> 章节。</p>
<p>redirect(局部刷新/单页刷新)</p>
<pre><code class="language-php">// 跳转并提示成功信息
$form-&gt;saved(function (Form $form) {
return $form-&gt;response()-&gt;success('保存成功')-&gt;redirect('auth/user');
});
// 跳转并提示错误信息
$form-&gt;saved(function (Form $form) {
return $form-&gt;response()-&gt;error('系统错误')-&gt;redirect('auth/user');
});</code></pre>
<p>仅返回错误信息但不跳转</p>
<pre><code class="language-php">$form-&gt;saving(function (Form $form) {
return $form-&gt;response()-&gt;error('系统异常');
});</code></pre>
<p>也可以通过抛出异常的形式展示错误信息</p>
<pre><code class="language-php">$form-&gt;submitted(function ($form) {
throw new \Exception('禁止访问');
});</code></pre>
<p><img src="https://cdn.learnku.com/uploads/images/202109/14/38389/S0KtwNRYGK.png!large" alt="" /></p>
<h3>返回字段验证出错信息</h3>
<p>通过<code>responseValidationMessages</code>方法可以很方便的返回字段验证出错信息,而不需要使用<code>Laravel validation</code>功能。</p>
<p>普通使用</p>
<pre><code class="language-php">protected function form()
{
return Form::make(new Model(), function (Form $form) {
if (...) { // 验证逻辑
$form-&gt;responseValidationMessages('title', 'title格式错误');
// 如有多个错误信息,第二个参数可以传数组
$form-&gt;responseValidationMessages('content', ['content格式错误', 'content不能为空']);
}
});
}</code></pre>
<p>在事件中使用
> {tip} 此方法仅在<code>submitted</code>事件中可用</p>
<pre><code class="language-php">$form-&gt;submitted(function (Form $form) {
// 接收表单参数
$title = $form-&gt;title;
if (...) { // 验证逻辑
$form-&gt;responseValidationMessages('title', 'title格式错误');
// 如有多个错误信息,第二个参数可以传数组
$form-&gt;responseValidationMessages('content', ['content格式错误', 'content不能为空']);
}
});</code></pre>