CakePHP多选控件选项显示JSON及虚拟字段name为null问题解决
CakePHP多选择器选项填充异常问题及解决方案
问题描述
在CakePHP项目中实现多选择器时,选项无法正常填充,存在两处异常:
- 即便显式指定了
keyField和valueField,选项值依然显示为JSON格式 name字段显示为null,不符合预期
错误输出示例:
<option value="0">{ "id": 8263, "name": null, "sort": "1" }</option>
现有配置说明
基础配置
clientsMySQL表字段:id, name_en, name_fr...- Client实体代码:
protected $_virtual = [ 'name', ]; protected function _getName() { if (Configure::read('wetkit.lang') == 'fr'){ return $this->get('name_fr'); } else { return $this->get('name_en'); } }
- ClientsTable配置:
$this->setDisplayField('name');
原控制器代码
// 构造查询,将已选客户端排在前列 $selected_clients = $this->Clients->find() ->select(['id' => 'id','name' => 'name_'.$this->lang,'sort'=>1]) ->where(['id in' => $user_clients]); $clients = $this->Clients->find() ->select(['id' => 'id','name' => 'name_'.$this->lang,'sort'=>2]) ->where(['id not in' => $user_clients]); $clients->unionAll($selected_clients)->epilog('order by sort asc, name asc');
生成的SQL语句
( SELECT id AS `id`, name_en AS `name`, 2 AS `sort` FROM clients Clients WHERE id not in (8263) ) UNION ALL ( SELECT id AS `id`, name_en AS `name`, 1 AS `sort` FROM clients Clients WHERE id in (8263) ) order by sort asc, name asc
原视图代码
<?= $this->Form->control('clients._ids', ['options' => $clients, 'label'=>__('Client'), 'keyField' => 'id', 'valueField' => 'name', 'values' => $user_clients]) ?>
解决方案
核心问题是手动设置的name查询别名和虚拟字段冲突,同时联合查询后的排序字段需要匹配ORM的命名规则,修复后的控制器代码如下:
// 构造查询,将已选客户端排在前列 $selected_clients = $this->Clients->find() ->select(['id','name_en','name_fr','sort'=>1]) ->where(['id in' => $user_clients]); $clients = $this->Clients->find() ->select(['id','name_en','name_fr','sort'=>2]) ->where(['id not in' => $user_clients]); $clients->unionAll($selected_clients) ->epilog('order by sort, Clients__name_'.$this->lang); $clients = $clients->combine('id','name_'.$this->lang);
修复点说明:
- 不再手动给多语言名称字段设置
name别名,保留原生字段名让虚拟字段_getName可以正常读取对应语言的字段值 - 联合查询后的排序字段调整为ORM映射的别名格式
Clients__name_xx,避免排序失效 - 直接使用
combine方法将查询结果转为id-名称的键值对数组,无需在视图层再指定keyField和valueField
可将该逻辑封装为公共组件,供项目内其他有类似多语言、已选置顶需求的模型复用。
内容的提问来源于stack exchange,提问作者TechFanDan
相关产品推荐
相关产品推荐

