Laravel-admin 复杂查询过滤器注意事项及一个「高级技巧」

TL;DR

相信 Laravel-admin 应该是社区里妇孺皆知的了,其作者 @song 可谓是居功至伟,几乎凭个人一己之力把中国 Laravel“艺术家”们的幸福程度拉升到世界级水准。

我个人从 Laravel-admin 这个产品受益颇多,只可惜 song 他自己看似收获极少,以至于好像有两三年没有再对其进行迭代更新了。咱们社区专门有一个 Dcat Admin 中文文档 ,相信明眼人一下就能看出这个 Dcat Admin 其实就是 Laravel-admin 的衍生产品。在这里惟愿 song 一切安好吧!

正文

话说我的一个基于 Laravel-admin 的项目今天遇到一个得用到 filter 复杂查询过滤器的需求。先上个图:

看着很平平无奇,实则暗藏玄机。

首先,「商家」数据比较多,是需要通过 Ajax 方式加载的 select 组件;其次「品类」是每个商家自己定义的,所以是需要根据选择的商家再加载的 multipleSelect 组件。

Laravel-admin 官方文档在 filter 选择框及复杂查询这块介绍得不多,例如 select 只说是参考 model-form 的。实际用下来会遇到问题,这就是本文标题中提到的:

注意事项

$filter->equal('shop_id', '所属商家')->ajax('api/shops')->load('shop_cates','api/shop_cates');

如果是写成上面这样,是会报错的(Call to a member function load() on null)。但这种写法在 model-form 里就没问题。在 filter 里正确的写法是:

$filter->equal('shop_id', '所属商家')->load('shop_cates','api/shop_cates')->ajax('api/shops');

ok,注意事项说完了。希望能帮你节省一点试错的时间。下面要讲「高级技巧」了 :satisfied:

高级技巧

上面提到的「品类」首先是「商品」的一个属性,其实它又是每个「商家」不同的。所以在数据的关联关系上均是多对多( BelongsToMany ),这里就不作代码示例了。

因此,要对「商品」的「品类」进行查询过滤,这里不得不用到复杂查询:

$filter->where(function ($query) {
    $query->whereHas('shop_cates', function ($query) {
        $query->where('shop_cate_id', $this->input);
    });
}, '所属品类')->multipleSelect();

这时候麻烦来了:上面的 selecet 联动不生效

查看网页源代码发现:复杂查询的 multipleSelect 没有 shop_cates 这个属性,取而代之的是一个随机字符串。那么我的挑战就是如何实现这个 select 联动。不知道社区里有没有人遇到过类似情况,反正我是头一次。官方文档自然是没有相关说明的,网上也几乎搜不到相关介绍。这也是我写这篇博文的原因,希望下次有人需要的时候能看到吧。

这里不多赘述了,直接上最终代码:

$s = $filter->equal('shop_id', '所属商家');
$f = $filter->where(function ($query) {
    $query->whereHas('shop_cates', function ($query) {
        $query->where('shop_cate_id', $this->input);
    });
}, '所属品类');

$s->select()->load($f->getColumn(), 'api/shop_cates')->ajax('api/shops');
$f->multipleSelect();

最终的代码看着很简洁吧?但是很不容易才搞定的。这里的关键点首先是使用 getColumn()multipleSelect 的实际属性给找到,其次是 $s$f 的顺序及拼接。有兴趣的铁子们不妨试试,本文完。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!