【问题标题】:cakephp string field used to create checkboxescakephp 用于创建复选框的字符串字段
【发布时间】:2012-05-24 01:03:17
【问题描述】:

我正在使用 cakephp 2.1,让我告诉你:我就是喜欢它。
在我的表单中,我有一个可以有多个答案(复选框)的字段。
我不想为每个选项创建一个数据库字段,也不想使用 HABTM。

更新:

因为我需要几组标志,所以我采用了 $hasAndBelongsToMany 方式。 (也可以在不修复代码但编辑表格的情况下添加新标志(例如,通过 phpmyadmin)。

1.- 为我需要的每组标志制作一个表格/模型:

2.- 在我的主模型中,声明与每个的关系:

var $hasAndBelongsToMany = array('Sample','Format','Report','Openend','Dataproce','Prefield');  

3.- 在我的主控制器中,为每个表填充一个数组以供使用:

$openends = $this->Project->Openend->find('list', array(
                    //'order' => 'name'
            ));

4.- 并使用视图中的数组:

echo $this->Form->input('Dataproce', array('label' => false, 'type' => 'select', 'multiple' => 'checkbox', 'size' => 2));  

=== 老问题从这里开始;正确答案仅适用于一组标志 ===

我想保存一个字符串并用它来神奇地创建一组属于单个数据字段的复选框。

我已经在其中了。

我的看法:

echo $this->Form->input('pr_reports', array('type' => 'select',
                             'multiple' => 'checkbox',
                             'options' => array('0' => 'Interrnal',
                                                '1' => 'Disposition',
                                                '2' => 'Web Disposition',
                                                '3' => 'Marginal',
                                                '4' => 'Custom')))

我的控制器添加方法,保存前

        // Used serialize() to convert the array to string
        $dataString = serialize($this->request->data['Project']['pr_reports']);
        $this->request->data['Project']['pr_reports'] = $dataString;

字符串被保存好了(看起来编码但没问题:a:5:{i:0;s)

我的问题是在编辑记录以使复选框相应地检查自己时,我该怎么做?也就是说,我在哪里 unserialize() 字符串字段并在编辑视图上处理它?

有没有更好的方法?

非常感谢您的帮助。

卡洛斯·加西亚

==== 解决后,有多个字段具有不同标志集的麻烦
数据只保存一个字段,忽略另一个 ====

你好;
如前所述,对于表格中的一个字段,它可以正常工作;
我很难使用另一个字段(单独的一组标志)。
似乎只附加了一种行为;我想知道我是否应该以不同的方式附加它们。

我的领域:

pr_data_format` tinyint(3) unsigned NOT NULL,
pr_report_format` tinyint(3) unsigned NOT NULL,  

我的控制器

$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_data_formats', 'bits'=>'Project::pr_data_formats'));
$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_report_formats', 'bits'=>'Project::pr_report_formats'));

我的模特

        const STATUS_ASCII = 1;
        const STATUS_SPSS = 2;
        const STATUS_EXCEL = 4;
        const STATUS_CUSTOM = 8;

        public static function pr_data_formats($value = null) {
            $options = array(
                self::STATUS_ASCII => __('ASCIId'),
                self::STATUS_SPSS => __('SPSSBd'),
                self::STATUS_EXCEL => __('Exceld'),
                self::STATUS_CUSTOM => __('Customd'),
            );
            return parent::enum($value, $options);
        }                    


        const REP_ASCII = 1;
        const REP_SPSS = 2;
        const REP_EXCEL = 4;
        const REP_CUSTOM = 8;

        public static function pr_report_formats($value = null) {
            $options = array(
                self::REP_ASCII => __('ASCIIr'),
                self::REP_SPSS => __('SPSSBr'),
                self::REP_EXCEL => __('Excelr'),
                self::REP_CUSTOM => __('Customr'),
            );
            return parent::enum($value, $options);
        }                                

我的看法

echo $this->Form->input('pr_data_formats', array('options' => Project::pr_data_formats(), 'multiple' => 'checkbox'));
echo $this->Form->input('pr_report_formats', array('options' => Project::pr_report_formats(), 'multiple' => 'checkbox'));

就是想不通,试过了:

$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_report_formats', 'bits'=>'Project::pr_report_formats'), array('mappedField'=>'pr_data_formats', 'bits'=>'Project::pr_data_formats'));  

但没用,只更新了一个字段。

你能帮忙吗?我们将使用大约 4 或 5 个标志集。

非常感谢。

卡洛斯

【问题讨论】:

  • 这看起来不像你应该做的 ;) ID 不是 2^x (1,2,4,8,...),你不应该手动序列化。不过,我从未测试过两个不同的复选框。但它应该能够以某种方式使其工作。
  • 我可以很好地处理一个字段;直到现在,我才复制了整个内容以拥有另一个带有其他标志的字段。您是说它只能与表中的 1 个字段一起使用,而不能与 2 个或更多字段一起使用?你提到我不应该手动序列化....我不知道在哪里。我真的很感激任何帮助。谢谢!!
  • 更新:由于我需要几组标志,我选择了 $hasAndBelongsToMany 方式。 (允许在不修复代码但编辑表格的情况下添加新标志(例如通过 phpmyadmin)。非常感谢马克。

标签: arrays cakephp checkbox


【解决方案1】:

做到这一点的正确方法是使用行为。这使您的模型保持干净,只需将其放入模型中即可应用于多个模型:

public $actsAs = array('MyBehavior');

现在,为了进行序列化,我使用了 Jsonable Behavior: http://www.dereuromark.de/2011/07/05/introducing-two-cakephp-behaviors/ 它基本上使您的输入数组在保存时成为可存储的字符串,并在读取时将字符串返回到数组。您可以根据自己的需要轻松调整。

但是对于您想要对多个复选框执行的操作,还有一个更好的东西 - 位掩码。我开发了一种所谓的 Bitmasked 行为 - 你需要使用 1,2,4,8,... 但除此之外它是相同的: http://www.dereuromark.de/2012/02/26/bitmasked-using-bitmasks-in-cakephp/ 我完全用它来做同样的事情。

【讨论】:

  • 马克,非常感谢。我读过你的博客,这似乎是一个完美的解决方案。我已将 BitmaskedBehavior.php 放在 /Model/Behavior 文件夹中。然后将public $actsAs = array('Search.Searchable','Bitmasked'); 添加到我的模型中,并将$this->Project->Behaviors->attach('Bitmasked', array('mappedField'=>'pr_reports')); 添加到我的控制器中。我收到错误“未找到位”。我是 cakephp 的新手,请您添加步骤以使其正常工作吗?我的意思是,把这个放在这里,把这个放在那里有点帮助。不要误会我的意思,我做我的功课。请帮忙。再次感谢您。
  • 如果您通过 $acts 全局声明它,因为您不需要动态附加它;)一次就可以了。您还需要将位掩码值传递给您的行为(使用位掩码属性)。因此,如果您在静态方法reportTypes 中将它们声明为我的枚举,则应将'bits'=>'Project::reportTypes' 传递给$actsAs = array('Bitmasked'=>array(...)) 中的行为声明。
  • 谢谢马克;我想我快到了。我得到:'致命错误:调用 C:\wamp\www\dev.opm.asc\app\Model\project.php 中未定义的方法 AppModel::enum()' 因为我不知道该怎么做定义枚举。
  • 谢谢马克;我想我快到了。我收到:'致命错误:调用 ...\app\Model\project.php 中未定义的方法 AppModel::enum()。因为我不确定如何定义枚举。您提到需要通过扩展 MyModel 或手动将其放入您的 AppModel 来定义 MyModel::enum... value, $options, $default = '') {if ($value !== null) {if (array_key_exists($value, $options)) { ..etc...} 你能否详细说明一下应该如何我定义 MyModel::enum?非常感谢!
  • 小心 - 它应该是 Project.php(大小写很重要 - 总是)。此外,您一直走在正确的轨道上 - 如果您将其复制到您的 AppModel 中,那么您的模型应该扩展这个 AppModel。一旦你了解了继承的工作原理,它就相当简单了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-31
  • 2013-02-26
  • 2020-08-24
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
相关资源
最近更新 更多