如何正确地从控制器传递多个列表到视图?

时间:2014-04-18 12:37:28

标签: cakephp cakephp-2.4

这是我简化的问题描述。我有几个包含相似列的表,其中包含不同的数据:

table_one.id, table_one.name, ..., table_one.foo
table_two.id, table_two.name, ..., table_two.foo

table_one.foo允许的值为'a','b','c',

table_two.foo允许的值为'x','y','z'。

在视图中我有一个表单,允许在table_one和table_two中输入几条记录:

$this->Form->input('TableOne.0.foo', array('type' => 'select'));
$this->Form->input('TableOne.1.foo', array('type' => 'select'));
$this->Form->input('TableOne.2.foo', array('type' => 'select'));
...
$this->Form->input('TableTwo.0.foo', array('type' => 'select'));
$this->Form->input('TableTwo.1.foo', array('type' => 'select'));
$this->Form->input('TableTwo.2.foo', array('type' => 'select'));

在控制器中,我构建列表并将它们传递给视图:

$tableOneFooList = array('a', 'b', 'c');
$tableTwoFooList = array('x', 'y', 'z');
$this->set('foo', $tableOneFooList);

问题在于我无法设置第二个foo变量,并且$tableOneFooList被填充到所有6个选择框中。我可以在控制器中以不同的方式命名列表但是在视图中需要更多工作才能在验证失败后选择正确的值。是否有一种将列表传递给视图的好方法,以便在提交后表单不验证时,将保留选定的值?也许我不知道一些命名惯例?

2 个答案:

答案 0 :(得分:1)

据我所知,表单助手魔术无法区分这两个字段,您要么必须单独传递列表,要么使用自定义表单助手。

使用options选项

单独传递列表时,您只需使用options option,必要时CakePHP将根据请求中传递的值自动选择相应的列表条目。

<强>控制器

$tableOneFoos = array('a', 'b', 'c');
$tableTwoFoos = array('x', 'y', 'z');
$this->set(compact('tableOneFoos', 'tableTwoFoos'));

查看

$this->Form->input('TableOne.0.foo', array('type' => 'select', 'options' => $tableOneFoos));
$this->Form->input('TableOne.1.foo', array('type' => 'select', 'options' => $tableOneFoos));
$this->Form->input('TableOne.2.foo', array('type' => 'select', 'options' => $tableOneFoos));

$this->Form->input('TableTwo.0.foo', array('type' => 'select', 'options' => $tableTwoFoos));
$this->Form->input('TableTwo.1.foo', array('type' => 'select', 'options' => $tableTwoFoos));
$this->Form->input('TableTwo.2.foo', array('type' => 'select', 'options' => $tableTwoFoos));

就是这样,在使用提交的数据呈现表单时,应该按预期选择值。

自定义表单助手

表单帮助程序检查字段名camelCased plurals的变量名称(请参阅FormHelper::_optionsOptions()),不考虑模型名称,因此在您的情况下,它将查找{{ 1}},这就是为什么你最后用这一个列表用于所有输入。

您可以覆盖该方法并实施使用模型名称的附加检查,以便帮助程序查找foostableOneFoos等变量。

这是一个未经测试的!例如:

tableTwoFoos

然后,您可以将App::uses('FormHelper', 'View/Helper'); class MyFormHelper extends FormHelper { protected function _optionsOptions($options) { $options = parent::_optionsOptions($options); if (!isset($options['options'])) { // this is where the magic happens, an entity name like // `Model_field` is turned into a variable name like // `modelFields` which is then used to lookup the view vars. $entityName = $this->model() . '_' . $this->field(); $varName = Inflector::variable( Inflector::pluralize(preg_replace('/_id$/', '', $entityName)) ); $varOptions = $this->_View->get($varName); if (is_array($varOptions)) { if ($options['type'] !== 'radio') { $options['type'] = 'select'; } $options['options'] = $varOptions; } } return $options; } } tableOneFoos传递给视图,而不使用输入的tableTwoFoosoptions选项:

<强>控制器

type

查看

$tableOneFoos = array('a', 'b', 'c');
$tableTwoFoos = array('x', 'y', 'z');
$this->set(compact('tableOneFoos', 'tableTwoFoos'));

只要没有以HABTM方式使用的$this->MyForm->input('TableOne.0.foo'); $this->MyForm->input('TableOne.1.foo'); $this->MyForm->input('TableOne.2.foo'); $this->MyForm->input('TableTwo.0.foo'); $this->MyForm->input('TableTwo.1.foo'); $this->MyForm->input('TableTwo.2.foo'); TableOneFoo模型,这应该有效,因为它们的字段最终会使用相同的变量名称,即TableTwoFootableOneFoos

答案 1 :(得分:0)

不要让这复杂 - 简单的解决方案是 -

<?php
$tableOneFooList = array('a', 'b', 'c');
$tableTwoFooList = array('x', 'y', 'z');

echo $this->Form->create();
echo $this->Form->input('TableOne.0.foo', array('type' => 'select', 'options' => $tableOneFooList));
echo $this->Form->input('TableOne.1.foo', array('type' => 'select', 'options' => $tableOneFooList));
echo $this->Form->input('TableOne.2.foo', array('type' => 'select', 'options' => $tableOneFooList));
echo $this->Form->input('TableTwo.0.foo', array('type' => 'select', 'options' => $tableTwoFooList));
echo $this->Form->input('TableTwo.1.foo', array('type' => 'select', 'options' => $tableTwoFooList));
echo $this->Form->input('TableTwo.2.foo', array('type' => 'select', 'options' => $tableTwoFooList));
echo $this->Form->end('Submit');
?>