表单字段动态显示
<h1>表格数据源</h1>
<p>数据仓库(<code>Repository</code>)是一个可以提供特定接口对数据进行读写操作的类,通过数据仓库的引入,可以让页面的构建不再关心数据读写功能的具体实现,开发者只需要实现特定的操作接口即可轻松切换数据源。关于数据仓库的详细用法请参考文档<a href="model-repository.md">数据仓库</a>。</p>
<p>> {tip} 表格的数据是通过 <code>Dcat\Admin\Contracts\Repository::get</code> 接口获取的。</p>
<p><a name="model"></a></p>
<h2>数据来自模型</h2>
<p>> {tip} 如果你的数据来自<code>Model</code>,那么你也可以直接使用<code>Model</code>实例,底层会自动把<code>Model</code>转化为数据仓库实例。</p>
<p>当数据源支持<code>Eloquent Model</code>时,只需创建一个简单的<code>Repository</code>类继承<code>Dcat\Admin\Repositories\EloquentRepository</code>即可</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Repositories;
use Dcat\Admin\Repositories\EloquentRepository;
use App\Models\Movie as MovieModel;
class Movie extends EloquentRepository
{
// 这里定义你的模型类名
protected $eloquentClass = MovieModel::class;
// 通过这个方法可以指定查询的字段,默认&quot;*&quot;
public function getGridColumns()
{
return [$this-&gt;getKeyName(), 'name', 'title', 'created_at'];
}
}</code></pre>
<h3>直接使用模型</h3>
<p>如果你还觉得创建 <code>Repository</code> 类麻烦,也可以直接把 <code>Eloquent Model</code> 的实例传递到 <code>Grid</code> 中,底层会自动把 <code>Eloquent Model</code> 转化为 <code>EloquentRepository</code> 实例 </p>
<pre><code class="language-php">use App\Models\Movie as MovieModel;
$grid = new Grid(new MovieModel());
...</code></pre>
<h3>修改来源数据</h3>
<p>1、使用 <code>Grid\Model</code></p>
<pre><code class="language-php">use App\Admin\Repositories\Movie;
$grid = new Grid(new Movie());
// 添加默认查询条件
$grid-&gt;model()-&gt;where('id', '&gt;', 100);
// 设置初始排序条件
$grid-&gt;model()-&gt;orderBy('id', 'desc');
...
</code></pre>
<p>其它查询方法可以参考<code>eloquent</code>的查询方法。</p>
<p>2、使用 <code>Model Query</code></p>
<pre><code class="language-php">use App\Models\Movie as MovieModel;
$grid = new Grid(MovieModel::where('id', '&gt;', 100));
...</code></pre>
<h3>关联数据</h3>
<p>有以下三种方式让你的表格支持关联数据</p>
<p>1、使用Repository</p>
<pre><code class="language-php">use App\Admin\Repositories\Movie;
// 相当于 MovieModel::with('categories')
$grid = new Grid(new Movie(['categories']));
$grid-&gt;categories;
...</code></pre>
<p>2、使用 <code>Grid\Model</code></p>
<pre><code class="language-php">use App\Admin\Repositories\Movie;
$grid = new Grid(new Movie());
$grid-&gt;model()-&gt;with('categories');
$grid-&gt;categories;
...</code></pre>
<p>3、使用 <code>Model Query</code></p>
<pre><code class="language-php">use App\Models\Movie as MovieModel;
$grid = new Grid(MovieModel::with('categories'));
$grid-&gt;categories;
...</code></pre>
<p><a name="api"></a></p>
<h2>数据来自外部API</h2>
<p><a name="example"></a></p>
<h3>示例</h3>
<p>如果数据是来自外部的API,只需要覆写<code>Repository</code>中的<code>get</code>方法既可, 具体用法可参考下面的示例,采用<code>豆瓣电影</code>API获取并展示数据:</p>
<p>> {tip} 需要注意的是分页和不分页的情况下<code>get</code>方法返回的参数值类型是不同的,具体使用可参考<a href="model-repository.md#get">数据仓库 - get</a>。</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Repositories;
use Dcat\Admin\Grid;
use Dcat\Admin\Repositories\Repository;
use Illuminate\Pagination\LengthAwarePaginator;
class ComingSoon extends Repository
{
protected $api = 'https://api.douban.com/v2/movie/coming_soon';
/**
* 定义主键字段名称
*
* @return string
*/
public function getPrimaryKeyColumn()
{
return '_id';
}
/**
* 查询表格数据
*
* @param Grid\Model $model
* @return LengthAwarePaginator
*/
public function get(Grid\Model $model)
{
// 当前页数
$currentPage = $model-&gt;getCurrentPage();
// 每页显示行数
$perPage = $model-&gt;getPerPage();
// 获取排序字段
[$orderColumn, $orderType] = $model-&gt;getSort();
// 获取&quot;scope&quot;筛选值
$city = $model-&gt;filter()-&gt;input(Grid\Filter\Scope::QUERY_NAME, '广州');
// 如果设置了其他过滤器字段,也可以通过“input”方法获取值,如:
$title = $model-&gt;filter()-&gt;input('title');
if ($title !== null) {
// 执行你的筛选逻辑
}
$start = ($currentPage - 1) * $perPage;
$client = new \GuzzleHttp\Client();
$response = $client-&gt;get(&quot;{$this-&gt;api}?{$this-&gt;apiKey}&amp;city=$city&amp;start=$start&amp;count=$perPage&quot;);
$data = json_decode((string)$response-&gt;getBody(), true);
return $model-&gt;makePaginator(
$data['total'] ?? 0, // 传入总记录数
$data['subjects'] ?? [] // 传入数据二维数组
);
}
}</code></pre>
<p><a name="grid-model"></a></p>
<h3>Grid\Model 常用方法</h3>
<p><a name="getCurrentPage"></a></p>
<h4>获取当前页数 (getCurrentPage)</h4>
<p>获取当前页码</p>
<ul>
<li>返回值: <code>int|null</code> 如果不允许分页返回null
<pre><code class="language-php">$page = $model-&gt;getCurrentPage();</code></pre></li>
</ul>
<p><a name="getPerPage"></a></p>
<h4>获取每页显示行数 (getPerPage)</h4>
<p>获取每页显示行数</p>
<ul>
<li>返回值: <code>int|null</code> 如果不允许分页返回null
<pre><code class="language-php">$limit = $model-&gt;getPerPage();</code></pre></li>
</ul>
<p><a name="getSort"></a></p>
<h4>获取排序字段 (getSort)</h4>
<p>获取排序字段</p>
<ul>
<li>返回值: <code>array</code> <code>[$orderColumn, 'desc'|'asc']</code> || <code>[null, null]</code></li>
</ul>
<pre><code class="language-php">// $orderColumn 字段名称,如没有进行排序则为 null
// $orderType 正序或倒序: &quot;desc&quot;、&quot;asc&quot;,如没有进行排序则为 null
list($orderColumn, $orderType) = $model-&gt;getSort();</code></pre>
<p><a name="getFilter"></a></p>
<h4>获取过滤器对象 (filter)</h4>
<p>获取过滤器对象,通过过滤器对象可以获取到搜索表单的值,用法如下</p>
<ul>
<li>返回值 <code>Dcat\Admin\Grid\Filter</code></li>
</ul>
<pre><code class="language-php">// 获取&quot;scope&quot;筛选值
$city = $model-&gt;filter()-&gt;input(Grid\Filter\Scope::QUERY_NAME, '广州');
// 如果设置了其他过滤器字段,也可以通过“input”方法获取值,如:
$title = $model-&gt;filter()-&gt;input('title');
if ($title !== null) {
// 执行你的筛选逻辑
}</code></pre>
<h4>获取快捷搜索表单值</h4>
<p>通过以下方式可以获取到快捷搜索表单值</p>
<pre><code class="language-php">$quickSearch = $model-&gt;grid()-&gt;quickSearch()-&gt;value();</code></pre>
<p><a name="sql"></a></p>
<h2>数据来自复杂SQL查询</h2>
<p>如果来源数据需要执行比较复杂的SQL语句获取,那么有两个办法, 第一个办法就是上面的方法,覆盖掉<code>Repository</code>的<code>get</code>方法实现。</p>
<p>> {tip} 需要注意的是分页和不分页的情况下<code>get</code>方法返回的参数值类型是不同的,具体使用可参考<a href="model-repository.md#get">数据仓库 - get</a>。</p>