JSON 数组作为 select 选项和空显示名称
JSON array as select options and null displayname
我无法正确填充多个 select。
- 即使我指定了
keyField
和 valueField
,我得到的选项值是 JSON
name
为空,不应为
示例:
<option value="0">{
"id": 8263,
"name": null,
"sort": "1"
}</option>
clients
MySQL table 列: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
table:
$this->setDisplayField('name');
控制器:
//build query to highlight selected clients
$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]) ?>
解决方案:
这似乎有效。我确实必须找出合适的排序来反映 ORM 的字段名称(即 Client__name_en
)。我还将其包装在一个组件中,并且可以使用其他模型在应用程序范围内使用。
//build query to highlight selected clients
$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);
keyField
和valueField
选项属于list
查找器,不构成控件。
$clients
->unionAll($selected_clients)
->find('list', [
'keyField' => 'id',
'valueField' => 'name',
])
// ...
看起来有点奇怪,但可以说是可以链接查找器。或者,您可以直接使用 Collection::combine()
,这是使用 list
查找器时自动应用的内容:
'options' => $clients->combine('id', 'name'),
// ...
而 name
是 null
,因为您没有 select 您的实体尝试查找的 name_en
或 name_fr
字段。选择一个值作为 name
不会规避实体的访问器方法,当您尝试访问实体上的 name
字段时,它总是 运行,无论该字段的值是否存在.
访问器方法将接收可能存在的字段的值作为其第一个参数,因此您可以使用它,类似于:
protected function _getName($name)
{
if ($name !== null) {
return $name;
}
// ...
}
然而,这一切都有些挑剔且容易出错,最终实体行为绑定到应用程序状态对未来来说并不是一个好兆头。也许您应该试试 CakePHP 的内置翻译功能。
另见
我无法正确填充多个 select。
- 即使我指定了
keyField
和valueField
,我得到的选项值是 JSON name
为空,不应为
示例:
<option value="0">{
"id": 8263,
"name": null,
"sort": "1"
}</option>
clients
MySQL table 列: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
table:
$this->setDisplayField('name');
控制器:
//build query to highlight selected clients
$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]) ?>
解决方案:
这似乎有效。我确实必须找出合适的排序来反映 ORM 的字段名称(即 Client__name_en
)。我还将其包装在一个组件中,并且可以使用其他模型在应用程序范围内使用。
//build query to highlight selected clients
$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);
keyField
和valueField
选项属于list
查找器,不构成控件。
$clients
->unionAll($selected_clients)
->find('list', [
'keyField' => 'id',
'valueField' => 'name',
])
// ...
看起来有点奇怪,但可以说是可以链接查找器。或者,您可以直接使用 Collection::combine()
,这是使用 list
查找器时自动应用的内容:
'options' => $clients->combine('id', 'name'),
// ...
而 name
是 null
,因为您没有 select 您的实体尝试查找的 name_en
或 name_fr
字段。选择一个值作为 name
不会规避实体的访问器方法,当您尝试访问实体上的 name
字段时,它总是 运行,无论该字段的值是否存在.
访问器方法将接收可能存在的字段的值作为其第一个参数,因此您可以使用它,类似于:
protected function _getName($name)
{
if ($name !== null) {
return $name;
}
// ...
}
然而,这一切都有些挑剔且容易出错,最终实体行为绑定到应用程序状态对未来来说并不是一个好兆头。也许您应该试试 CakePHP 的内置翻译功能。
另见